日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树学习之二叉查找树

發(fā)布時(shí)間:2024/8/23 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树学习之二叉查找树 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

寫在前面的話

最近接到幾個(gè)大學(xué)同學(xué)研究生畢業(yè)不是簽華為就是簽百度,本人取經(jīng)得到:操作系統(tǒng)、數(shù)據(jù)結(jié)構(gòu)與算法、網(wǎng)絡(luò)編程與數(shù)據(jù)庫是面試中利器。想想自己工作2.5年月薪還不到10K,過著苦逼的碼農(nóng)生活,而他們一出校門就是大放光芒(最起碼進(jìn)入的公司就讓人覺得牛逼哄哄的).本人痛定思痛,決定下大功夫?qū)W習(xí)一下數(shù)據(jù)結(jié)構(gòu)與算法,我想這應(yīng)該是根本吧.
之前也看過數(shù)據(jù)結(jié)構(gòu),但是一看到那亂七八糟的關(guān)系,就覺得還是研究一下別的東西,結(jié)果就是好多東西都是淺嘗輒止,知子皮毛.
本人只貼出學(xué)習(xí)過程中的代碼,以及一些發(fā)雜算法函數(shù)的詳細(xì)注釋,還有就是學(xué)習(xí)過程中遇到過的好的講解URL,以供自己理解和后續(xù)的復(fù)習(xí)鞏固,有不對(duì)的地方還需指正.

學(xué)習(xí)二叉樹之前總感覺很抽象,最近看到亞嵌一個(gè)關(guān)于紅黑樹講解的視頻用到一個(gè)命令,能夠?qū)⒍鏄滢D(zhuǎn)換成圖形打印出來,感覺很神奇,這個(gè)工具在Linux C編程一站式學(xué)習(xí) 中有提到過,
http://www.essex.ac.uk/linguistics/external/clmt/latex4ling/trees/tree/
有關(guān)應(yīng)用會(huì)在后面代碼測(cè)試中有提到,我想這應(yīng)該是學(xué)習(xí)二叉樹的一大利器,在此提出來。

源碼

binarytree.h
#ifndef BINARYTREE_H #define BINARYTREE_Htypedef struct node *link; /***節(jié)點(diǎn)中的數(shù)據(jù)類型重定義*/ typedef unsigned char TElemType;struct node { TElemType item; link lchild, rchild; };link init(TElemType VLR[], TElemType LVR[], int n);void pre_order(link t, void (*visit)(link)); void in_order(link t, void (*visit)(link)); void post_order(link t, void (*visit)(link)); void pprint(link t); int count(link t); int depth(link t); void destroy(link t);/** *http://www.cnblogs.com/bizhu/archive/2012/08/19/2646328.html 算法圖解 * *二叉排序樹(Binary Sort Tree)又稱二叉查找樹(Binary Search Tree),亦稱二叉搜索樹, *它或者是一棵空樹;或者是具有下列性質(zhì)的二叉樹: *(1)若左子樹不空,則左子樹上所有結(jié)點(diǎn)的值均小于它的根結(jié)點(diǎn)的值; *(2)若右子樹不空,則右子樹上所有結(jié)點(diǎn)的值均大于它的根結(jié)點(diǎn)的值; *(3)左、右子樹也分別為二叉排序樹; *(4)排序二叉樹的中序遍歷結(jié)果是從小到大排列的. * *二叉查找樹相比于其他數(shù)據(jù)結(jié)構(gòu)的優(yōu)勢(shì)在于查找、插入的時(shí)間復(fù)雜度較低,為O(log n)。 *二叉查找樹是基礎(chǔ)性數(shù)據(jù)結(jié)構(gòu),用于構(gòu)建更為抽象的數(shù)據(jù)結(jié)構(gòu),如集合、multiset、關(guān)聯(lián)數(shù)組等。 * *搜索,插入,刪除的復(fù)雜度等于樹高,期望O(log n),最壞O(n)(數(shù)列有序,樹退化成線性表) *改進(jìn)版的二叉查找樹可以使樹高為O(logn),如SBT,AVL,紅黑樹等. * *程序來源于Linux C編程一站式學(xué)習(xí) */ link bstSearch(link t, TElemType key); link bstInsert(link t, TElemType key); link bstDelete(link t, TElemType key);/***http://baike.baidu.com/view/593144.htm?fr=aladdin*平衡二叉樹*/#endifbinarytree.c /* binarytree.c */ #include <stdio.h> #include <stdlib.h> #include "binarytree.h"/***生成節(jié)點(diǎn)*@param item is node value*@returns link point to new node*/ static link make_node(TElemType item) {link p = malloc(sizeof *p);p->item = item;p->lchild = p->rchild = NULL;return p; }/***釋放節(jié)點(diǎn)*@param link to free*/ static void free_node(link p) {free(p); }/***根據(jù)前序與中序序列來初始化二叉樹*@param VLR 前序序列*@param LVR 中序序列*@param n 序列中數(shù)值個(gè)數(shù)*@returns NULL when n <= 0*@returns link pointer to new binarytree*/ link init(TElemType VLR[], TElemType LVR[], int n) {link t;int k;if (n <= 0)return NULL;for (k = 0; VLR[0] != LVR[k]; k++);t = make_node(VLR[0]);t->lchild = init(VLR+1, LVR, k);t->rchild = init(VLR+1+k, LVR+1+k, n-k-1);return t; }#ifdef RECU /***前序遍歷(跟左右)*@param t to visit*@param visit point to a func*/ void pre_order(link t, void (*visit)(link)) {if (!t)return;visit(t);pre_order(t->lchild, visit);pre_order(t->rchild, visit); }/***中序序遍歷(左跟右)*@param t to visit*@param visit point to a func*/ void in_order(link t, void (*visit)(link)) {if (!t)return;in_order(t->lchild, visit);visit(t);in_order(t->rchild, visit); }/***中序序遍歷(左右跟)*@param t to visit*@param visit point to a func*/ void post_order(link t, void (*visit)(link)) {if (!t)return;post_order(t->lchild, visit);post_order(t->rchild, visit);visit(t); } #endif/***遍歷二叉樹,生成用于tree工具的字符串*@param root to visit*/ void pprint(link root) {printf("(");if (root != NULL) {printf("%d", root->item);pprint(root->lchild);pprint(root->rchild);}printf(")"); }int count(link t) {if (!t)return 0;return 1 + count(t->lchild) + count(t->rchild); }int depth(link t) {int dl, dr;if (!t)return 0;dl = depth(t->lchild);dr = depth(t->rchild);return 1 + (dl > dr ? dl : dr); }void destroy(link t) {post_order(t, free_node); }/***在bst中查找值為key的節(jié)點(diǎn)**1、若b是空樹,則搜索失敗,否則;*2、若x等于b的根節(jié)點(diǎn)的數(shù)據(jù)域之值,則查找成功;否則;*3、若x小于b的根節(jié)點(diǎn)的數(shù)據(jù)域之值,則搜索左子樹;否則;*4、查找右子樹.**@param t to search*@param key the value of link to find*@returns the link of the key*/ link bstSearch(link t, TElemType key) {if (t == NULL)return NULL;if (t->item > key) {return bstSearch(t->lchild, key);} else if (t->item < key){return bstSearch(t->rchild, key);} else {return t;} }/***在bst中插入值為key的節(jié)點(diǎn)**1、若t是空樹,則將key作為根節(jié)點(diǎn)的值插入,否則;*2、若t->item大于key,則把key插入到左子樹中,否則;*3、把key插入到左子樹中.**@param t 要插入的 bst*@param key 要插入的值*@returns 插入后的bst*/ link bstInsert(link t, TElemType key) {if (t == NULL) {return make_node(key);}if (t->item > key) {t->lchild = bstInsert(t->lchild, key);} else {t->rchild = bstInsert(t->rchild, key);}return t; }/***在bst中刪除值為key的節(jié)點(diǎn)**1、若t為空樹,則直接返回NULL,否則;*2、若t->item大于key,bst左子樹為bst左子樹刪除key后的bst,否則;*3、若t->item小于key,bst右子樹為bst右子樹刪除key后的bst,否則;*4、若t->item == key:* 1.若其左右子樹為NULL,返回NULL,即對(duì)其父節(jié)點(diǎn)賦值為NULL* 2.若其左子樹不為NULL,則在其左子樹中找到最大節(jié)點(diǎn)p,將p->item賦值給當(dāng)前節(jié)點(diǎn),還需要在其左子樹中刪除p->item,3.若其右子樹不為NULL,則在其左子樹中找到最小節(jié)點(diǎn)p,將p->item賦值給當(dāng)前節(jié)點(diǎn),還需要在其右子樹中刪除p->item,**@param t 要插入的 bst*@param key 要插入的值*@returns 插入后的bst*/ link bstDelete(link t, TElemType key) {if (t == NULL)return NULL;if (t->item > key) t->lchild = bstDelete(t->lchild, key);else if (t->item < key)t->rchild = bstDelete(t->rchild, key);else {link p;if (t->lchild == NULL && t->rchild == NULL) {free_node(t);t = NULL;} else if (t->lchild){for (p = t->lchild; p->rchild; p = p->rchild);t->item = p->item;t->lchild = bstDelete(t->lchild, t->item);} else {for (p = t->rchild; p->lchild; p = p->lchild);t->item = p->item;t->rchild = bstDelete(t->rchild, t->item);}}return t; }測(cè)試程序 /* main.c */ #include <stdio.h> #include <time.h> #include "binarytree.h"#define RANGE 50 #define N 15void print_item(link p) {printf("%d\t", p->item); }void testBst() {int i;link root = NULL;srand(time(NULL));for (i=0; i<N; i++)root = bstInsert(root, rand()%RANGE);printf("\\tree");pprint(root);printf("\n");TElemType key = rand() % RANGE;if (bstSearch(root, key)) {bstDelete(root, key);printf("\n%d\n", key);printf("\\tree");pprint(root);printf("\n");} }void testInitByList() {TElemType pre_seq[] = { 4, 2, 1, 3, 6, 5, 7 };TElemType in_seq[] = { 1, 2, 3, 4, 5, 6, 7 };link root = init(pre_seq, in_seq, 7);printf("\\tree");pprint(root);printf("\n");pre_order(root, print_item);putchar('\n');in_order(root, print_item);putchar('\n');post_order(root, print_item);putchar('\n');printf("count=%d depth=%d\n", count(root), depth(root));destroy(root);printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); }int main() {//testInitByList();testBst();return 0; }

對(duì)應(yīng)的Makefie

#if you want to use recursive func,please make recu=y ifeq (y, $(recu))CFLAGS += -DRECU endififeq (y, $(debug))CFLAGS += -g endifall:gcc $(CFLAGS) main.c binarytree.c binarytree.h -o treeclean:$(RM) tree

編譯測(cè)試

在這里遍歷二叉樹只寫了遞歸函數(shù)
在編譯的時(shí)候用一下命令
make recu=y debug=y運(yùn)行結(jié)構(gòu)如下: \tree(15(6(0()())(7()(14(11(8()())())())))(41(36(18(16()())(23(22()())(29()())))())(41()())))22 \tree(15(6(0()())(7()(14(11(8()())())())))(41(36(18(16()())(23()(29()())))())(41()())))好了接下來就是用工具tree,把這些字符串圖形化 echo "\tree(15(6(0()())(7()(14(11(8()())())())))(41(36(18(16()())(23(22()())(29()())))())(41()())))" | tree -b2怎么樣這個(gè)效果。

把b2改成b6

總結(jié)

以上是生活随笔為你收集整理的二叉树学习之二叉查找树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。