程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> c說話完成二叉查找樹實例辦法

c說話完成二叉查找樹實例辦法

編輯:關於C++

c說話完成二叉查找樹實例辦法。本站提示廣大學習愛好者:(c說話完成二叉查找樹實例辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是c說話完成二叉查找樹實例辦法正文


以下為算法具體流程及其完成。因為算法都用偽代碼給出,就免了一些文字描寫。


/*******************************************
=================JJ日志=====================
作者: JJDiaries(阿呆)
郵箱:[email protected]
日期: 2013-11-13
============================================
二叉查找樹,支撐的操作包含:SERACH、MINIMUM、
MAXIMUM、PREDECESSOR、SUCCESSOR、INSERT、DELETE。
定理:關於一個高度為h的二叉查找樹,操作SERACH、MINIMUM、
MAXIMUM、PREDECESSOR、SUCCESSOR的運轉時光均為O(h)
*******************************************/

/*================JJ日志=====================
作者: JJDiaries(阿呆)
郵箱:[email protected]
日期: 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,"谷歌"},
                     {345,"百度"},
                     {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:谷歌
key:256 words:JJDiaries
key:345 words:百度
key:543 words:nsfocus
Delete node(345,百度)
key:2 words:Viidiot
key:4 words:linux-code
key:123 words:谷歌
key:256 words:JJDiaries
key:543 words:nsfocus
free node(123,谷歌) now
free node(4,linux-code) now
free node(2,Viidiot) now
free node(543,nsfocus) now
free node(256,JJDiaries) now

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved