數據結構——零基礎建樹,二叉排序樹,AVL樹
遞歸
樹和圖非常重要的一個概念,即自己調用自己,如下是遞歸調用
的一個簡單程序,遞歸的結束條件必須要明確:
#include<stdio.h>
int fun(int n)
{
if(n<=1)
return 1;
else
return n+fun(n-1);
}
int main()
{
printf("%d",fun(5));
return 0;
}
二分查找
:在中的偶數數組裏找到對應數字的下標,找到返回下標,找不到返回
#include<stdio.h>
int fun(int n,int arr[],int min,int max)
{
printf("mid=%d max=%d\n",min,max);
if(min<=max)
{
int mid=(min+max)/2;
if(n==arr[mid])
return mid;
else if(n<arr[mid])
return fun(n,arr,min,mid-1);
else if(n>arr[mid])
return fun(n,arr,mid+1,max);
}
else
return -1;
}
int main()
{
int arr[101];
for(int i=1;i<=100;i++)
arr[i]=2*i;
printf("%d\n",fun(78,arr,0,100));
printf("%d\n",fun(9,arr,0,100));
return 0;
}
二叉樹
有度爲的結點。計算機中用鏈表存儲二叉樹
二叉樹的存儲和雙向鏈表
很像。
typedef struct Node{
char data;
struct Node* lchild;
struct Node* rchild;
}BTNode;
二叉樹的建立
二叉樹傳入參數得是指針,因爲函數傳形參,形參被函數改變後實參不改變,故必須傳指針,傳的時候取地址。
void BuildBT(BTnode** tree)
{
chae ch;
scanf("%c",&ch);//輸入數據
if(ch=="#")//如果這個節點數據是#則說明這個節點爲空
*tree=NuLL;
else{
*tree=(BTNode*)malloc(sizeof(BTNode));
//申請一個節點的內存
(*tree)->data=ch;//數據寫入到節點裏
BuildBT(&(*tree))->lchild);//遞歸建立左子樹
BuildBT(&(*tree))->rchild);
}
}
傳入修改指針的東西,即指針的指針,即傳入該節點左孩子的地址,申請一個新的節點,而左孩子自身作爲一個指針又指向根結點,所以傳入的是指針的指針。
二叉樹的銷燬
void DestroyBT(BTNode* tree)//傳入根結點
{
if(tree!=NULL)
{
DestroyBT(tree->lchild);
DestroyBT(tree->rchild);
free(tree);//釋放內存空間
}
}
只需要傳指針,不需要傳指針的指針,因爲不需要改變根結點的值了
注意 不能直接free根結點,因爲根結點free了,子節點並沒有消失,會造成內存的浪費。
二叉樹的遍歷
先序中序後序
先序中序後序都是指 根結點是先遍歷或者中間遍歷或者後遍歷,並且都是左子樹在右子樹前。
- 先序遍歷:對於當前節點,先輸出該節點,然後輸出他的左孩子,最後輸出他的右孩子。
- 中序遍歷:對於當前結點,先輸出它的左孩子,然後輸出該結點,最後輸出它的右孩子。
- 對於當前結點,先輸出它的左孩子,然後輸出它的右孩子,最後輸出該結點。
先序遍歷
void preorder(BTNode* node)
{
if(node==NULL)
return;
ekse
{
printf("%c",node->data);
preorder(node->lchild);
preorder(node->rchild);
}
}
中序遍歷
{
preorder(node->lchild);
printf("%c",node->data);
preorder(node->rchild);
}
後序遍歷
{
preorder(node->lchild);
preorder(node->rchild);
printf("%c",node->data);
}
求二叉樹的高度
int GetHeight(BTNode* node){
int Height=0;
if(node==NULL)
return 0;
//樹的高度=max(左子樹高度,右子樹高度)+1
else{
int L_Height=GetHeight(node->lchild);
int R_Height=GetHeight(node->rchild);
Height=L_Height>=R_Height?L_Height+1:R_Height+1;
}
return Height;
}
二叉樹的運用——二叉排序樹/排序二叉樹/二叉查找樹/二叉搜索樹()
二叉排序樹:或者是一棵空樹,或者是具有下列性質的二叉樹:
- 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
- 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
- 它的左、右子樹也分別爲二叉排序樹。
二叉排序樹的中序遍歷是從小到大
二叉查找樹自動排序,二叉查找樹的長相和給的無序序列的順序有關,搜索、插入、刪除的時間複雜度等於樹高,最優(時),最(數列有序,樹退化成線性表,如右斜樹,或者理解爲插入序列本身有序則查找效率退化爲O(n))。
用解決插入的序列爲有序序列查找效率直接退化成的問題。
:它或者是顆空樹,或者是具有下列性質的二叉樹:
- 它的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值不超過。
- 若將二叉樹節點的平衡因子定義爲該節點的左子樹的深度減去它的右子樹的深度,則平衡二叉樹上所有節點的平衡因子只可能爲-1,0,1.
- 只要二叉樹上有一個節點的平衡因子的絕對值大於,那麼這顆平衡二叉樹就失去了平衡。
參考內容
011-數據結構-樹與二叉樹的代碼基礎-遞歸的基本概念和使用
012-數據結構-代碼實現二叉樹的創建和銷燬
013-數據結構-二叉樹前序中序後序代碼講解
014-數據結構-排序二叉樹-二叉搜索樹-平衡二叉樹
樹的前序遍歷、中序遍歷、後序遍歷詳解
二叉排序樹