數據結構——零基礎建樹,二叉排序樹,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;
} 

二分查找:在02000\sim200中的偶數數組裏找到對應數字的下標,找到返回下標,找不到返回1-1

#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;
}

二叉樹

有度爲0,1,20,1,2的結點。計算機中用鏈表存儲二叉樹
二叉樹的存儲和雙向鏈表很像。

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;
} 

二叉樹的運用——二叉排序樹/排序二叉樹/二叉查找樹/二叉搜索樹(Binary  Sort  TreeBinary\,\, Sort\,\, Tree)

二叉排序樹:或者是一棵空樹,或者是具有下列性質的二叉樹:

  • 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值
  • 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值
  • 它的左、右子樹也分別爲二叉排序樹

二叉排序樹的中序遍歷是從小到大

二叉查找樹自動排序,二叉查找樹的長相和給的無序序列的順序有關,搜索、插入、刪除的時間複雜度等於樹高,最優O(logn)O(logn)(AVLAVL時),最O(n)O(n)(數列有序,樹退化成線性表,如右斜樹,或者理解爲插入序列本身有序則查找效率退化爲O(n))

AVLAVL樹

AVLAVL解決插入的序列爲有序序列查找效率直接退化成O(n)O(n)的問題。
AVLAVL:它或者是顆空樹,或者是具有下列性質的二叉樹:

  • 它的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值不超過11
  • 若將二叉樹節點的平衡因子BFBF定義爲該節點的左子樹的深度減去它的右子樹的深度,則平衡二叉樹上所有節點的平衡因子只可能爲-1,0,1.
  • 只要二叉樹上有一個節點的平衡因子的絕對值大於11,那麼這顆平衡二叉樹就失去了平衡。

在這裏插入圖片描述

參考內容

011-數據結構-樹與二叉樹的代碼基礎-遞歸的基本概念和使用
012-數據結構-代碼實現二叉樹的創建和銷燬
013-數據結構-二叉樹前序中序後序代碼講解
014-數據結構-排序二叉樹-二叉搜索樹-平衡二叉樹
樹的前序遍歷、中序遍歷、後序遍歷詳解
二叉排序樹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章