“樹”的常用代碼總結(數據結構)
首先本文采用的主要是採用二叉樹的二叉鏈表存儲
//二叉樹的二叉鏈表存儲表示
BiTNode 其實就是 Binary(二)Tree(樹) Node(結點)
包括 數據域 和 左右孩子結點的指針域
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//樹的二叉鏈表(孩子 - 兄弟)存儲表示
typedef struct CSNode
{
int data;
struct CSNode *firstchild, *nextsibling;
}CSNode, *CSTree;
//創建二叉樹(先序輸入&遞歸建立)
按先序遍歷順序輸入二叉樹的各個結點值,#表示空節點,建立二叉樹。
void CreatBiTree(BiTree &T)
{
char ch;
scanf("%c",&ch);
if(ch == '#')
{
T = NULL;
}
else
{
T = (BiTree)malloc(sizeof(BiTNode));
T->data = ch;
CreatBiTree(T->lchild);
CreatBiTree(T->rchild);
}
}
//二叉樹遍歷(遞歸)
這裏展示的是二叉樹的中序遍歷和先序遍歷,只要稍微變一下printf("%c",T->data);的位置。printf("%c",T->data);相當於遍歷時每個雙親。它在什麼位置,就是什麼遍歷。
二叉樹先序遍歷(遞歸)
void PreOrderTraverse(BiTree T)
{
if(T)
{
printf("%c",T->data); //先序遍歷此條語句在前面
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
二叉樹中序遍歷(遞歸)
void InOrderTraverse(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
printf("%c",T->data); //中序遍歷此條語句在中間
InOrderTraverse(T->rchild);
}
}
二叉樹後序遍歷(遞歸)
//後序遍歷二叉樹
void PostOrderBiTree(BiTree T)
{
if (T)
{
PostOrderBiTree(T->lChild);
PostOrderBiTree(T->rChlid);
printf("%d ", T->data); //後序遍歷此條語句在最後
}
}
//求二叉樹的深度(高度)
int TreeDeep(BiTree T)
{
int deep = 0;
if(T)
{
int leftdeep = TreeDeep(T->lchild);
int rightdeep = TreeDeep(T->rchild);
deep = leftdeep>=rightdeep?leftdeep+1:rightdeep+1;
}
return deep;
}
//由二元組建立孩子兄弟二叉樹
以雙親孩子二元組(F,C)的形式自上而下、自左而右依次輸入樹的各邊,建立樹的孩子-兄弟鏈表
void CreateCSTree(CSTree &T)
{
int input[2],n,i;
CSTree queue[MAXSIZE];
int front,rear;
CSTree p, q;
scanf("%d",&n);
//對隊列初始化
front = rear = 0;
for (i=0; i<n; i++)
{
scanf("%d",&input[0]);
scanf("%d",&input[1]);
//創建當前孩子結點
p = (CSTree)malloc(sizeof(CSNode));
p->data = input[1];
//孩子結點和兄弟結點賦值爲空
p->firstchild = p->nextsibling = NULL;
//將剛剛創建好的當前孩子結點放入隊尾
queue[rear] = p;
rear = (rear+1)%MAXSIZE;
/*********找雙親*********/
//如果是根結點,則不需找雙親
if (input[0] == -1)
{
T = p; //將剛剛創建的結點賦值爲根結點
}
//如果不是根結點,則找雙親
else
{
//從頭到尾遍歷當前所有兄弟找雙親,得到雙親的指針
for (q=queue[front]; q->data!=input[0];)
{
//如果隊頭元素和當前雙親結點不同,則出隊
//最終獲得的指針即其雙親的指針
front=(front+1)%MAXSIZE;
q=queue[front];
}
/*找到雙親後找哥哥*/
//如果找到的雙親還不存在孩子結點
if (!q->firstchild)
{
q->firstchild=p;
}
//如果已有孩子結點。則要找到最近的哥哥
else
{
for(q=q->firstchild; q->nextsibling; q=q->nextsibling);
q->nextsibling = p;//和哥哥連接
}
}
}
return 0;
}
//求孩子兄弟鏈表表示的樹 T的深度
int depthCSTree(CSTree T)
{
int maxd, d;
CSTree p;
if(!T) return 0; //空樹
else
{
for(maxd=0,p=T->firstchild; p; p=p->nextsibling)
if((d=depthCSTree(p)) > maxd) maxd = d; //子樹的最大深度
return maxd + 1;
}
}
//輸出孩子兄弟鏈表表示的樹 T所有葉子結點值
void InOrderTraverse_leaf(CSTree T)
{
if(T)
{
if(!T->firstchild)
{
printf("%d ",T->data);
}
InOrderTraverse_leaf(T->firstchild);
InOrderTraverse_leaf(T->nextsibling);
}
}
//二元組建樹並求其葉子結點和深度
此代碼用到的所有函數在上面已經全部展示過了
其中 system(“color F0\n”); 語句可以將控制檯變爲白底黑字
int main()
{
system("color F0\n");
CSTree T;
int deep;
CreateCSTree(T);
InOrderTraverse_leaf(T);
printf("\n");
deep = depthCSTree(T);
printf("%d\n",deep);
}
//求每個結點的深度
此時在二叉樹的存儲結構中添加一個深度元素,像這樣:
typedef struct BiTNode
{
char data;
int deep;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void node_deep(BiTree &T)
{
if(T)
{
if(T->lchild)
T->lchild->deep = T->deep + 1;
if(T->rchild)
T->rchild->deep = T->deep + 1;
node_deep(T->lchild);
node_deep(T->rchild);
}
}
如果還有什麼想要的關於樹的函數可以在評論區留言!看到就會盡快更新