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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言手撸搜索(查找)二叉树---创建,插入,删除

發布時間:2025/3/19 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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);

查找函數

算法的基本思路:

  • 若二叉排序樹為空樹,則查找失敗。
  • 將給定值key與根節點的關鍵字比較,若相等,則查找成功。
  • 將給定值key小于根節點的關鍵字,則在左子樹查找,否則在右子樹查找。
  • 代碼:

    //查找值在二叉樹中的位置 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為葉子結點;
  • 由于刪除葉子結點不影響二叉樹的特性,所以可以直接刪除,即只需要將刪除節點的父節點的相應指針域改為空指針即可。

  • 要刪除的節點p只有左子樹或者只有右子樹。
  • 只需將左子樹的根節點或者右子樹的根節點取代要刪除節點位置即可。

  • 待刪除節點的左、右子樹均非空。
  • 首先找到節點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语言手撸搜索(查找)二叉树---创建,插入,删除的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。