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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

数据结构(8-3)二叉排序树(查找、插入删除)

發布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构(8-3)二叉排序树(查找、插入删除) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一、基礎理論

1、特點:?

2、結構:?

二、查找

三、插入

四、刪除

1、被刪除的結點D是葉子結點

2、被刪除的結點D僅有一個孩子

2-1、刪除結點14(有左無右)

2-2、刪除結點?10?(有右無左)

3、被刪除結點的左右孩子都存在

方法一:以左子樹最大結點替換根結點

方法二:以右子樹最小結點替換根結點

總代碼

參考資料


一、基礎理論

1、特點:?

(1) 若它的左子樹不空,則?左子樹?上所有結點的值?均小于?它的根結點的值;

(2) 若它的右子樹不空,則?右子樹?上所有結點的值?均大于?它的根結點的值;

(3) 它的?左、右子樹又分別為二叉排序樹?。

2、結構:?

二叉樹

?

?

二、查找

(1)從根開始,未找到,則獲取空結點地址,返回;

(2)相等則找到,提示,退出;

(3)key < 結點,向左遍歷(遞歸lchild

(4)key > 結點,向右遍歷(遞歸rchild

(查找的同時還可以進行定位,最后返回需要查找的位置)

(和二分查找比較相似)

查找結點13

第一步:訪問根結點?8?.

第二步:根據二叉排序樹的左子樹均比根結點小,右子樹均比根結點大的性質,?13 > 8?,因此值為13的結點可能在根結點 8 的右子樹當中,我們查看根結點的右子節點?10?:

第三步:與第二步相似,?13 > 10?,因此查看結點?10?的右孩子?14?:

第四步:根據二叉排序樹的左子樹均比根結點小,右子樹均比根結點大的性質,?13 < 14?,因此查看?14?的左孩子 ?13?,發現剛好和要查找的值相等:

//查找二叉排序樹
void Search_BST(pBiTree* T, int key)		//關鍵字
{//查找失敗(沒有值,需要添加)if (!(*T)){p = T;return;}//查找成功if (key == (*T)->data){printf("查找成功!\n");success = 1;return;}else if (key < (*T)->data)Search_BST(&((*T)->lchild), key);		//小,往左遍歷elseSearch_BST(&((*T)->rchild), key);		//大,往右遍歷
}

三、插入

查找定位到待插入的位置,直接進行插入。?

首結點放入根,后面的依次與前面的每一個結點判斷,小則放在左邊大則放在右邊

插入全部

?代碼

//插入二叉排序樹
void Insert_BST(int key)			//索引
{Search_BST(&head, key);//找到if (success)return;//未找到(創建新結點,容納)(*p) = (pBiTree)malloc(sizeof(pBiTree));(*p)->data = key;				//存儲//給左右子樹賦空值(*p)->lchild = NULL;(*p)->rchild = NULL;
}

四、刪除

刪除操作與查找和插入操作不同,我們要分以下三種情況進行處理:

1、被刪除的結點D是葉子結點

從二叉排序樹當中直接刪除即可,也不會影響樹的結構。

2、被刪除的結點D僅有一個孩子

(1)如果只有左孩子,沒有右孩子,那么只需要把要刪除結點的左孩子鏈接到要刪除結點的父親節點,然后刪除D結點就好了;(覆蓋

(2)如果只有右孩子,沒有左孩子,那么只要將要刪除結點D的右孩子重接到要刪除結點D的父親結點。(覆蓋

2-1、刪除結點14(有左無右

覆蓋

保存要刪除結點?14?的?左孩子?結點?13?到臨時變量 temp,并刪除結點?14

將刪除結點?14?的父結點?10?的?右孩子?設置為 temp,即結點?13

2-2、刪除結點?10?(有右無左

覆蓋

保存要刪除結點?10?的?右孩子?結點?14?到臨時變量 temp,并刪除結點?10

將刪除結點?10?的父結點?8?的?右孩子?設置為 temp,即結點?14

3、被刪除結點的左右孩子都存在

用左子樹中的最大值或者右子樹中的最小值替換頂點

(對于這種情況就復雜一些了,這一次我們將圖變得復雜一點兒,給原來結點?10?增加了一個左孩子結點?9?。)

對于上面的二叉排序樹的中序遍歷結果如下所示:

刪除頂點8為例:?

方法一:以左子樹最大結點替換根結點

(1)獲取左子樹中的最大結點7

(2)將刪除結點?8?的值替換為?7?

(3)刪除根結點左子樹當中值最大結點(要考慮好該結點有無左孩子

方法二:以右子樹最小結點替換根結點

(1)查找刪除結點?8?的右子樹當中值最小的結點,即?9?

(2)將刪除結點?8?的值替換為?9?

(3)刪除根結點右子樹當中值最小的結點(要考慮好該結點有無右孩子

代碼1:定位到待刪除的結點

//刪除(定位到刪除的結點)
void Delete_BST(pBiTree* p, int key)
{if (*p)			//結點存在{if (key == (*p)->data)Delete(p);else if (key < (*p)->data)Delete_BST(&(*p)->lchild, key);		//遞歸左elseDelete_BST(&(*p)->rchild, key);		//遞歸右}
}

代碼2:單結點刪除

//刪除結點
void Delete(pBiTree* p)
{pBiTree s;//1、左右均為空if (!(*p)->lchild && !(*p)->rchild)*p = NULL;//2、左子樹為空else if (!(*p)->lchild)*p = (*p)->rchild;		//覆蓋//3、右子樹為空else if (!(*p)->rchild)*p = (*p)->lchild;		//覆蓋//4、左右子樹均不為空(兩個方法:找左子樹最大值/找右子樹最小值)//這里選擇找左子樹最大值else{pBiTree q = (*p);s = (*p)->lchild;			//先定位左子樹while (s->rchild){q = s;					//保存上一結點s = s->rchild;			//往后找}(*p)->data = s->data;		//覆蓋//考慮:存在左結點p = &q;						//定位到上一節點(*p)->rchild = s->lchild;	//重接q右子樹}
}

總代碼

//二叉排序樹(查找,插入,刪除)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>#define MAXSIZE 20
int data[MAXSIZE];
int length = 0;					//數組長度
int success = 0;				//記錄是否查找成功//二叉樹結構體
typedef struct BiTree
{int data;struct BiTree* lchild, * rchild;
}BiTree, * pBiTree, ** p2BiTree;
BiTree* head;
pBiTree* p;//輸入數據
void Input()
{int Data;int i = 0;printf("請輸入初始數據:\t");//輸入數據do{scanf("%d", &Data);data[i++] = Data;} while (getchar() != '\n');length = i;			//記錄數組長度
}//二叉樹初始化
void Init_BiTree()
{head = NULL;
}//查找二叉排序樹
void Search_BST(pBiTree* T, int key)		//關鍵字
{success = 0;				//初始化,不影響查找結果//查找失敗(沒有值,需要添加)if (!(*T)){p = T;return;}//查找成功if (key == (*T)->data){printf("查找成功!\n");success = 1;return;}else if (key < (*T)->data)Search_BST(&((*T)->lchild), key);		//小,往左遍歷elseSearch_BST(&((*T)->rchild), key);		//大,往右遍歷
}//插入
void Insert_BST(int key)					//索引
{Search_BST(&head, key);//找到if (success)return;//未找到(創建新結點,容納)(*p) = (pBiTree)malloc(sizeof(pBiTree));(*p)->data = key;				//存儲//給左右子樹賦空值(*p)->lchild = NULL;(*p)->rchild = NULL;
}//刪除結點
void Delete(pBiTree* p)
{pBiTree s;//1、左右均為空if (!(*p)->lchild && !(*p)->rchild)*p = NULL;//2、左子樹為空else if (!(*p)->lchild)*p = (*p)->rchild;		//覆蓋//3、右子樹為空else if (!(*p)->rchild)*p = (*p)->lchild;		//覆蓋//4、左右子樹均不為空(兩個方法:找左子樹最大值/找右子樹最小值)//這里選擇找左子樹最大值else{pBiTree q = (*p);s = (*p)->lchild;			//先定位左子樹while (s->rchild){q = s;					//保存上一結點s = s->rchild;			//往后找}(*p)->data = s->data;		//覆蓋//考慮:存在左結點p = &q;						//定位到上一節點(*p)->rchild = s->lchild;	//重接q右子樹}
}//刪除(定位到刪除的結點)
void Delete_BST(pBiTree* p, int key)
{if (*p)			//結點存在{if (key == (*p)->data)Delete(p);else if (key < (*p)->data)Delete_BST(&(*p)->lchild, key);		//遞歸左elseDelete_BST(&(*p)->rchild, key);		//遞歸右}
}//中序遍歷輸出
void Inorder_Traverse(pBiTree p)
{if (p){Inorder_Traverse(p->lchild);printf("%d ", p->data);Inorder_Traverse(p->rchild);}
}int main()
{int key;Input();							//輸入Init_BiTree();					    //二叉樹初始化for (int i = 0; i < length; i++)Insert_BST(data[i]);	        //插入二叉排序樹//刪除printf("\n請輸入需要刪除的數據:\t");scanf("%d", &key);Delete_BST(&head, key);//查找printf("請輸入需要查詢的數據:\t");scanf("%d", &key);Search_BST(&head, key);//插入printf("\n請輸入需要插入的數據:\t");scanf("%d", &key);Insert_BST(key);//查找Search_BST(&head, key);Inorder_Traverse(head);		//遍歷(中序遍歷,從小到大輸出)return 0;
}

參考資料

https://blog.csdn.net/kexuanxiu1163/article/details/106168677?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162884083916780271545792%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162884083916780271545792&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-106168677.ecpm_v1_rank_v29&utm_term=%E4%BA%8C%E5%8F%89%E6%8E%92%E5%BA%8F%E6%A0%91&spm=1018.2226.3001.4187

總結

以上是生活随笔為你收集整理的数据结构(8-3)二叉排序树(查找、插入删除)的全部內容,希望文章能夠幫你解決所遇到的問題。

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