【演算法導論】二叉排序樹
阿新 • • 發佈:2019-01-25
具體程式實現如下:
/**************************************\ 函式功能:在二叉排序樹中刪除節點 輸入: 二叉排序樹的根節點、要刪除的節點的內容 輸出: 二叉排序樹的根節點 \**************************************/ bstnode* DelBstNode(bstnode* t,int k) { bstnode *p,*q,*s,*f; p=t; q=NULL; while(p!=NULL)//查詢要刪除的內容為k的節點 { if(p->key==k) break; q=p; if(p->key<k) p=p->rchild; else p=p->lchild; } if(p==NULL) { printf("\n沒有找到該節點\n"); return t; } if(p->lchild==NULL) /* p所指結點的左子樹為空 */ { if (q==NULL) t=p->rchild; /* p所指結點是原二叉排序樹的根 */ else if (q->lchild==p) /* p所指結點是*q的左孩子 */ q->lchild=p->rchild; else q->rchild=p->rchild; /* 將p所指右子樹連結到*q的右指標域上 */ free(p); /* 釋放被刪結點 */ } else /* p所指結點有左子樹時,則按圖12.21(e)方法進行 */ { f=p; s=p->lchild; while(s->rchild!=NULL ) /* 在pL中查詢最右下結點 */ { f=s; s=s->rchild; } if ( f==p ) f->lchild=s->lchild; /* 將s所指結點的左子樹連結到*f上*/ else f->rchild=s->lchild; p->key=s->key; /* 將s所指結點的值賦給*p */ free(s); /* 釋放被刪結點 */ } return t; }
一個完整例項如下:
參考文獻:《計算機軟體技術基礎》 劉彥明 榮政 編 、《 演算法導論》#include<stdio.h> #include<malloc.h> #define maxsize 20 typedef struct node { int key; struct node*lchild,*rchild; }bstnode;//二叉排序樹的節點結構 bstnode* InsertBst(bstnode* t,bstnode* s);//二叉排序樹的插入 bstnode* CreatBst(int* arrayA,int n);//二叉排序樹的建立 void Layer(bstnode *p);//二叉排序樹的廣度優先遍歷 bstnode* DelBstNode(bstnode* t,int k);//二叉排序樹的刪除 void main() { int arrayA[9]={-1,5,2,4,3,1,6,7,8};//第一個節點沒有用於儲存資料,是為了方便計算 int n=sizeof(arrayA)/sizeof(int); bstnode *head=NULL;//初始化指向連結串列的頭指標 head=CreatBst(arrayA,n); printf("建立的二叉排序樹的廣度優先遍歷為:\n"); Layer(head); printf("\n刪除內容為5後的二叉排序樹的廣度優先遍歷為:"); head=DelBstNode(head,5); printf("\n"); Layer(head); } /**************************************\ 函式功能:向二叉排序樹中插入節點 輸入: 二叉排序樹的根節點、要插入的節點 輸出: 二叉排序樹的根節點 \**************************************/ bstnode* InsertBst(bstnode* t,bstnode* s) { bstnode *f,*p; p=t; while(p!=NULL) { f=p; if(s->key<=p->key) p=p->lchild; else p=p->rchild; } if(t==NULL) return s; if(s->key<f->key) f->lchild=s; else f->rchild=s; return t; } /**************************************\ 函式功能:建立二叉排序樹 輸入: 原始陣列 輸出: 二叉排序樹的根節點 \**************************************/ bstnode* CreatBst(int* arrayA,int n) { bstnode *t,*s; t=NULL; for(int i=1;i<n;i++) { s=(bstnode*)malloc(sizeof(bstnode)); s->key=arrayA[i];//從arrayA[1]開始 s->lchild=s->rchild=NULL; t=InsertBst(t,s);//呼叫插入函式 } return t; } /**************************************\ 函式功能:廣度優先遍歷二叉排序樹 輸入: 二叉排序樹的根節點 輸出: 無 \**************************************/ void Layer(bstnode *p) { bstnode* queue[maxsize];//queue陣列用於儲存節點地址 bstnode* s; int rear=0; //佇列尾指標 int front=0; //佇列頭指標 if(p!=NULL)//輸入的樹不為空 { rear=1; //初始化 front=0; queue[rear]=p; while(front<rear)//判斷佇列是否為空 { front++; s=queue[front]; printf("%d ",s->key); if(s->lchild!=NULL) //儲存左右子節點 { rear++; queue[rear]=s->lchild; } if(s->rchild!=NULL) { rear++; queue[rear]=s->rchild; } } } } /**************************************\ 函式功能:在二叉排序樹中刪除節點 輸入: 二叉排序樹的根節點、要刪除的節點的內容 輸出: 二叉排序樹的根節點 \**************************************/ bstnode* DelBstNode(bstnode* t,int k) { bstnode *p,*q,*s,*f; p=t; q=NULL; while(p!=NULL)//查詢要刪除的內容為k的節點 { if(p->key==k) break; q=p; if(p->key<k) p=p->rchild; else p=p->lchild; } if(p==NULL) { printf("\n沒有找到該節點\n"); return t; } if(p->lchild==NULL) /* p所指結點的左子樹為空 */ { if (q==NULL) t=p->rchild; /* p所指結點是原二叉排序樹的根 */ else if (q->lchild==p) /* p所指結點是*q的左孩子 */ q->lchild=p->rchild; else q->rchild=p->rchild; /* 將p所指右子樹連結到*q的右指標域上 */ free(p); /* 釋放被刪結點 */ } else /* p所指結點有左子樹時,則按圖12.21(e)方法進行 */ { f=p; s=p->lchild; while(s->rchild!=NULL ) /* 在pL中查詢最右下結點 */ { f=s; s=s->rchild; } if ( f==p ) f->lchild=s->lchild; /* 將s所指結點的左子樹連結到*f上*/ else f->rchild=s->lchild; p->key=s->key; /* 將s所指結點的值賦給*p */ free(s); /* 釋放被刪結點 */ } return t; }
注:如果程式出錯,可能是使用的開發平臺版本不同,請點選如下連結: 解釋說明