亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

c語言實現二叉查找樹實例方法

2020-01-26 15:42:11
字體:
來源:轉載
供稿:網友

以下為算法詳細流程及其實現。由于算法都用偽代碼給出,就免了一些文字描述。

復制代碼 代碼如下:

/*******************************************
=================JJ日記=====================
作者: JJDiaries(阿呆)
郵箱:JJDiaries@gmail.com
日期: 2013-11-13
============================================
二叉查找樹,支持的操作包括:SERACH、MINIMUM、
MAXIMUM、PREDECESSOR、SUCCESSOR、INSERT、DELETE。
定理:對于一個高度為h的二叉查找樹,操作SERACH、MINIMUM、
MAXIMUM、PREDECESSOR、SUCCESSOR的運行時間均為O(h)
*******************************************/

/*================JJ日記=====================
作者: JJDiaries(阿呆)
郵箱:JJDiaries@gmail.com
日期: 2013-11-13
============================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORDLEN 16
//定義一個節點,除了存放key值外,還包含了一個data字符數組用于存放一個單詞
struct node{
    int key;
    char data[WORDLEN];
    struct node *parent;
    struct node *left;
    struct node *right;
};
typedef struct node * tree;

/*============================================
樹的中序遍歷
INORDER_TREE_WALK(x)
    if x!=NIL
        then INORDER_TREE_WALK(left[x])
             print key[x]
             INORDER_TREE_WALK(left[x])
============================================*/   
void inorder_tree_walk(tree T)
{
    if(T!=NULL){
        inorder_tree_walk(T->left);
        printf("key:%d   words:%s/n",T->key,T->data);
        inorder_tree_walk(T->right);
    }
}


/*============================================
樹的搜索,返回含有關鍵字k的結點
TREE_SEARCH(x,k) //遞歸版本
    if x=NIL or k =key[x]
        then return x
    if k<key[x]
        then return TREE_SEARCH(left[x],k)
        else return TREE_SEARCH(right[x],k)

TREE_SEARCH(x,k) //非遞歸版本
    while x!=NIL and k!= key[x]
        do if k<key[x]
            then x <―― left[x]
            else x <―― right[x]
    return x
============================================*/
//遞歸版本
struct node* tree_search(tree T,int k)
{
    if(T==NULL || k == T->key)
        return T;
    if(k < T->key)
        return tree_search(T->left,k);
    else
        return tree_search(T->right,k);
}
//非遞歸版本
struct node* tree_search1(tree T,int k)
{
    while(T!=NULL && T->key!=k)
        if(k < T->key)
            T=T->left;
        else
            T=T->right;
    return T;
}

/*============================================
返回key值最小的結點
TREE_MINIMUM(x)
    while left[x]!=NIL
        do x <―― left[x]
    return x
============================================*/   
struct node* tree_minimum(tree T)
{
    while(T->left != NULL)
        T=T->left;
    return T;
}

/*============================================
返回key值最大的結點
TREE_MAXMUM(x)
    while right[x]!=NIL
        do x <―― right[x]
    return x
============================================*/
struct node* tree_maxmum(tree T)
{
    while(T->right != NULL)
        T=T->right;
    return T;
}
/*============================================   
中序遍歷下,返回某一結點的后繼結點
1)如果結點x有右子結點,則其后繼結點為右子樹中最小結點。
2)如果結點x沒有右子樹,且x有一個后繼y,則y是x的最低祖先結點
且y的左兒子也是x的祖先。
TREE_SUCCESSOR(x)
    if right[x] != NIL
        return TREE_MINIMUM(right[x])
    y=p[x]
    while y!=NIL and x=right[y] //如果x=left[y],那么x的后繼就是y,跳出while循環,直接返回y即可
        do x <―― y
           y <―― p[y]
    return y
============================================*/   
struct node * tree_successor(struct node *T)
{
    if(T->right!=NULL)
        return tree_minimum(T->right);
    struct node *y=T->parent;
    while(y!=NULL && T == y->right){
        T=y;
        y=y->parent;
    }
    return y;
}


/*===========================================
插入操作
思路:從根節點一路往下尋找插入位置,用指針x跟蹤這條尋找路徑,并用指針y指向x的父結點
TREE_INSERT(T,z)
    y=NIL
    x=root[T]
    while x!= NIL //直到x為空,這個空位置即為需要插入的位置
        do y<―― x
            if key[z]<key[x]
                then x <―― left[x]
                else x <―― right[x]
    p[z]=y
    if y=NIL
        then root[T]=z //樹T為空時的情況
        else if key[z] < key[y]
            then left[y]=z //小于y的插在左邊,大于的插在右邊
            else right[y]=z
============================================*/   
void tree_insert(tree *PT,struct node *z)
{
    if(*PT==NULL){//樹為空,則將z作為根結點返回
        *PT=z;
        return;
    }
    struct node *y=NULL;
    struct node *x=*PT;
    while(x!=NULL){
        y=x;
        if(z->key < x->key)
            x=x->left;
        else
            x=x->right;
    }
    z->parent=y;
    if(z->key < y->key)
        y->left=z;
    else
        y->right=z;
}

/*===============================================
刪除操作
刪除操作分為三類情況:
1)若要刪除的節點z沒有子女,則只需修改z的父節點的該子女為NIL即可
2)若要刪除的節點z只有一個子女,則只需將z的這個子女與z的父節點連接起來即可
3)若要刪除的節點z有兩個子女,則需要先刪除z的后繼y,再用y的內容替換z的內容。
TREE_DELETE(T,z)
    if left[z]=NIL || right[z]=NIL  //把要刪除的節點先保存在y中
        then y <―― z 
        else y <―― TREE_SUCCESSOR(z)
    if left[y]!=NIL                 //將y的非空子女存放在x中
        then X <―― left[y]
        else x <―― right[y]
    if x!=NIL
        then p[x]=p[y]    //將要刪除節點的子女連接到要刪除節點的父節點上
    if p[y]=NIL     //如果要刪除的節點為根節點
        then root[T] <―― x
        else if y=left[p[y]]//
            then left[p[y]] <―― x
            else right[p[y]] <―― x
    if y!=z  //第三種情況,需要用y的內容替換z的內容
        then key[z] <―― key[y]
            copy y's other data to z
    return y
==============================================*/
struct node * tree_delete(tree *PT,struct node *z)
{
    struct node *delnode,*sonnode;
    if(z->left==NULL || z->right == NULL)//有一個子女或無子女,則要刪除的結點結尾z本身
        delnode=z;
    else                                 //有兩個子女,則要刪除的結點為z的后繼結點
        delnode=tree_successor(z);

    if(delnode->left!=NULL)
        sonnode=delnode->left;
    else
        sonnode=delnode->right;

    if(sonnode!=NULL)
        sonnode->parent=delnode->parent;
    if(delnode->parent==NULL)
        *PT=sonnode;
    else if(delnode->parent->left==delnode)
        delnode->parent->left=sonnode;
    else
        delnode->parent->right=sonnode;
    if(delnode!=z){
        z->key=delnode->key;
        strcpy(z->data,delnode->data);
    }
    return delnode;
}
//初始化一棵樹
tree init_tree(int key)
{   
    struct node * t;
    t=(tree)malloc(sizeof(struct node));
    if(t==NULL)
        return NULL;
    t->key=key;
    t->parent=t->left=t->right=NULL;
    return t;
}
//釋放資源
void fini_tree(tree T)
{
    if(T!=NULL){
        fini_tree(T->left);
        fini_tree(T->right);
        printf("free node(%d,%s) now/n",T->key,T->data);
        free(T);

    }
}
//測試程序
int main()
{
    tree myTree=init_tree(256);
    if(myTree==NULL)
        return 1;
    strcpy(myTree->data,"JJDiaries");
    struct record{
    int key;
    char word[WORDLEN];
    };
    struct record records[]={ {2,"Viidiot"},
                     {4,"linux-code"},
                     {123,"google"},
                     {345,"baidu"},
                     {543,"nsfocus"}
                    };
    int i;
    struct node *tmp;
    for(i=0;i<5;++i){
        tmp=(tree)malloc(sizeof(struct node));
        if(tmp==NULL)
            continue;
        tmp->key=records[i].key;
        strcpy(tmp->data,records[i].word);
        tmp->left=tmp->right=tmp->parent=NULL;
        tree_insert(&myTree,tmp);
    }
    inorder_tree_walk(myTree);
    struct node *del;
    del=tree_delete(&myTree,tree_search(myTree,345));
    printf("Delete node(%d,%s)/n",del->key,del->data);
    free(del);
    inorder_tree_walk(myTree);
    fini_tree(myTree);
}

程序運行結果:
jjdiaries@ubuntu>./search_tree
key:2 words:Viidiot
key:4 words:linux-code
key:123 words:google
key:256 words:JJDiaries
key:345 words:baidu
key:543 words:nsfocus
Delete node(345,baidu)
key:2 words:Viidiot
key:4 words:linux-code
key:123 words:google
key:256 words:JJDiaries
key:543 words:nsfocus
free node(123,google) now
free node(4,linux-code) now
free node(2,Viidiot) now
free node(543,nsfocus) now
free node(256,JJDiaries) now

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美一区二区三区……| 亚洲日韩中文字幕在线播放| 98精品在线视频| 亚洲自拍另类欧美丝袜| 国产精自产拍久久久久久蜜| 国产精品吴梦梦| 欧美一区视频在线| 久久精品国产一区二区电影| 国产日韩欧美日韩| 久久福利视频网| 国产日韩精品综合网站| 91亚洲永久免费精品| 91久久夜色精品国产网站| 欧美一级视频一区二区| 欧美性高潮床叫视频| 日韩在线高清视频| 精品久久久av| 久久精品电影网| 4444欧美成人kkkk| 亚洲精品国产精品自产a区红杏吧| 啊v视频在线一区二区三区| 国产精品久久久久久久久久久久| 91精品国产综合久久久久久蜜臀| 国产成人jvid在线播放| 久久免费视频网站| 亚洲成人av片在线观看| 亚洲欧美日韩一区二区三区在线| 欧美一区二粉嫩精品国产一线天| 国产精品视频成人| 777午夜精品福利在线观看| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲天堂av综合网| 亚洲黄页网在线观看| 日韩精品视频在线免费观看| 亚洲欧美日韩在线一区| 亚洲电影第1页| 成人黄色激情网| 国产精品美女视频网站| 国产精品国语对白| 91久久精品日日躁夜夜躁国产| 97色伦亚洲国产| 国产精品一区专区欧美日韩| 91精品国产成人www| 欧美夜福利tv在线| 日韩精品在线私人| 欧美在线免费视频| 日韩中文字幕精品| 日韩免费观看av| 国产精品h在线观看| 亚洲国产另类 国产精品国产免费| 日韩欧美国产中文字幕| 97视频在线观看视频免费视频| 久久精品国产欧美激情| 国产成人久久久| 亚洲成人激情小说| 国产91精品久久久| 国产一区二区香蕉| 在线亚洲欧美视频| 日本aⅴ大伊香蕉精品视频| 亚洲免费电影一区| 午夜免费在线观看精品视频| 96精品久久久久中文字幕| 亚洲高清免费观看高清完整版| 欧美极品欧美精品欧美视频| 国产精品久久久久久久久免费| 欧美大片在线免费观看| 亚洲电影中文字幕| 欧美一区二区大胆人体摄影专业网站| 欧美国产日韩二区| 国产成人精品一区二区在线| 国产精品福利观看| 国模gogo一区二区大胆私拍| 欧美激情亚洲精品| 成人av在线天堂| 91九色国产社区在线观看| 美女扒开尿口让男人操亚洲视频网站| 国产精品成人免费视频| 久久99热精品这里久久精品| 日韩精品视频在线| 国产成+人+综合+亚洲欧美丁香花| 国产欧美在线视频| 国内精品一区二区三区| 精品自在线视频| 欧美成人午夜影院| 欧美日韩国产精品一区二区不卡中文| 51视频国产精品一区二区| 精品国内自产拍在线观看| 久久99国产综合精品女同| 国产成人精品在线观看| 97精品视频在线观看| 97在线免费观看视频| 亚洲va欧美va国产综合久久| 欧美大片在线影院| 亚洲欧美综合区自拍另类| 国产精品自拍偷拍| 中文字幕免费精品一区高清| 亚洲人成电影网站色| 亚洲最大成人免费视频| 在线观看精品国产视频| 成人h视频在线观看播放| 午夜精品美女自拍福到在线| 欧美亚洲另类激情另类| 91色p视频在线| 欧美激情亚洲激情| 亚洲视频在线观看网站| 国产z一区二区三区| 久久色在线播放| 亚洲欧美制服另类日韩| 日韩精品在线观看一区| 亚洲国产小视频| 成人午夜在线影院| 超碰91人人草人人干| 亚洲欧美另类人妖| yw.139尤物在线精品视频| 国产一区二区三区18| 91免费看视频.| 亚洲精品二三区| 日韩精品极品视频| 国外成人免费在线播放| 亚洲激情国产精品| 色综合天天狠天天透天天伊人| 国产亚洲欧美日韩精品| 国产精品久久中文| 亚洲老头老太hd| 亚洲国产高清福利视频| 亚洲激情第一页| 国产成人精品日本亚洲专区61| 亚洲精品综合久久中文字幕| 高清一区二区三区日本久| 国产一区红桃视频| 欧美精品www| 亚洲精品电影网站| 九九热99久久久国产盗摄| 国产精品中文字幕在线| 亚洲国产欧美一区二区三区久久| 国产视频精品久久久| 伊人青青综合网站| 亚洲国产精品人人爽夜夜爽| www.亚洲人.com| 国产精品久久久av久久久| www.色综合| 久久久久久久国产精品视频| 日韩一区二区福利| 久久久中文字幕| 国产精品久久久一区| 久久精品小视频| 欧美国产精品va在线观看| 亚洲a级在线观看| 久久久极品av| 日韩精品极品毛片系列视频| 在线国产精品视频| 中文字幕亚洲欧美日韩2019| 欧美激情在线视频二区| 91精品视频在线免费观看| 久久亚洲精品国产亚洲老地址| 亚洲奶大毛多的老太婆| 久久精品免费电影| 国产一区二区三区网站| 日韩大胆人体377p| 亚洲无限av看| 成人精品一区二区三区| 在线观看日韩专区| 国产一区二区在线免费视频| 国产成人精品午夜|