C语言手撸搜索(查找)二叉树---创建,插入,删除
生活随笔
收集整理的這篇文章主要介紹了
C语言手撸搜索(查找)二叉树---创建,插入,删除
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C語言搜索(查找)二叉樹
- 存儲結構
- 函數聲明
- 查找函數
- 創建二叉樹
- 創建節點
- 創建節點數為n的搜索二叉樹
- 二叉樹的插入
- 刪除操作
存儲結構
//元素類型 #define TypeElem inttypedef struct BSTNode {TypeElem data;struct BSTNode * lchild;struct BSTNode* rchild; }BSTNode,*BSTree;函數聲明
//創建一個節點 BSTNode* Create_Node(TypeElem key); //創建二叉排序樹 void Create_BST(BSTree& T,int n); //查找值在二叉樹中的位置 BSTNode* Search_BST(BSTree T, int val); //查找該值在二叉樹的父節點 BSTNode* Search_Pre_BST(BSTree T, int val); //插入一個節點 void Insert_BST(BSTree node,int val); //刪除值為val的節點 void Delet_BST(BSTree& T,int val); //中序遞歸遍歷二叉樹的所有節點 void InOrder(BSTree T);查找函數
算法的基本思路:
代碼:
//查找值在二叉樹中的位置 BSTNode* Search_BST(BSTree T, int val) {while (T) {if (T->data == val)return T;else if (T->data < val)T = T->rchild;elseT = T->rchild;} }創建二叉樹
創建節點
//創建一個節點 BSTNode* Create_Node(TypeElem key) {BSTNode* node = (BSTNode*)malloc(sizeof(BSTNode));if (!node) {printf("申請空間失敗!\n");return 0;}node->data = key;//左右指針置為空是個好習慣node->lchild = node->rchild = NULL;return node; }創建節點數為n的搜索二叉樹
//創建含義n個元素的二叉排序樹 void Create_BST(BSTree& T, int n) {int x;BSTNode* node;while (n--) {scanf_s("%d", &x);//為空創建根節點,否則插入節點if (!T)T = Create_Node(x);elseInsert_BST(T, x);} }二叉樹的插入
二叉排序樹是一種動態樹表,其特點是樹的結構通常不是一次生成的,而是在查找過程中,當二叉樹查找失敗時,才進行插入,并且新插入的結點一定是一個新添加的葉子結點。其插入過程為:若二叉排序樹為空,則將新結點作為根結點插入。若二叉排序樹非空,則將新結點的關鍵字與二叉排序樹根結點的關鍵字比較,若與根結點關鍵字相等,則不插入,若小于根結點的關鍵字,則插入二叉排序樹的左子樹,若大于根結點的關鍵字,則插入二叉排序樹的右子樹。
代碼:
//插入一個節點 void Insert_BST(BSTree T, int val) {if (!T)printf("空\n");BSTree p = T,pre = NULL; //p 是工作指針,pre指向要插入節點的前一個位置// p非空while (p) {pre = p;// 存在該值后就不插入了if (val == p->data)return;else if (val > p->data)p = p->rchild;elsep = p->lchild;}//創建一個值為 val 的節點p = Create_Node(val);//如果比父節點大插入右邊if (val > pre->data)pre->rchild = p;elsepre->lchild = p; }刪除操作
刪除操作有以下幾種情況:(假設p為刪除的節點,f為其父節點)
由于刪除葉子結點不影響二叉樹的特性,所以可以直接刪除,即只需要將刪除節點的父節點的相應指針域改為空指針即可。
只需將左子樹的根節點或者右子樹的根節點取代要刪除節點位置即可。
首先找到節點p在中序序列的直接前驅節點s,然后用s的值替代節點p的值,再將節點s刪除。
代碼:
//刪除值為val的節點 void Delet_BST(BSTree& T,int val) {// 查找該值對應的節點BSTNode* f,*p;p = T;f = NULL;while (p) {if (p->data == val)break;f = p;if (p->data > val)p = p->lchild;elsep = p->rchild;}//如果節點非空if (p) {BSTNode* q, * s;/*情況一:如果左右子樹均不為空*/if (p->lchild && p->rchild) {//考慮左子樹的根沒有左子樹的情況q = p;//因為一個節點中序遍歷的前驅一定在其左子樹s = p->lchild;//同時因為中序遍歷順序為左根右,//根節點相當于其左子樹第一個節點的。//而在一個子樹中,要想從左跳到根,則必須遍歷完其右子樹。//所以從 s的右子樹找node節點的前驅。while (s->rchild) {// p存的是其前驅的前一個節點q = s;s = s->rchild;}//將node處的值用 其前驅的值代替p->data = s->data;//表明node的左子樹的第一個節點存在右子樹//則前驅所在節點為其前驅的右子樹位置if (q != p)q->rchild = s->lchild;elseq->lchild = s->lchild;free(s);}/*第二種情況:被刪除節點缺右子樹,包含左右子樹都缺的情況;缺右子樹就用左子樹去填*/else if (p->rchild == NULL) {//不是根節點/*則有兩種情況,* 1是節點位于父節點的左子樹,就令父節點的左子樹為節點的左子樹* 2是節點位于父節點的右子樹,就令父節點的右子樹為節點的左子樹*/if (f) {if (f->lchild == p) {f->lchild = p->lchild;p->lchild = NULL;}else {f->rchild = p->lchild;p->lchild = NULL;}//釋放刪除掉節點的空間free(p);}//如果是根節點表明根節點的右子樹為空,那么只需讓其左子樹替代其位置else {f = p;p = p->lchild;f->lchild = NULL;free(f);//記得更新更節點T = p;}}/*第三種情況:被刪除節點缺左子樹,包含左右子樹都缺的情況;缺右子樹就用右子樹去填*///步驟和第二種情況類似就不重復說明了else {if (f) {if (f->lchild == p) {f->lchild = p->rchild;p->rchild = NULL;}else {f->rchild = p->rchild;p->rchild = NULL;}free(p);}else {f = p;p = p->rchild;f->lchild = NULL;free(f);T = p;}}}else {printf("該值不存在!\n");} }總結
以上是生活随笔為你收集整理的C语言手撸搜索(查找)二叉树---创建,插入,删除的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言----预处理
- 下一篇: C语言操作MySQL-----又一个小技