1. 程式人生 > >用C語言將二叉樹轉換為雙向連結串列

用C語言將二叉樹轉換為雙向連結串列

樹是一種重要的資料結構,尤其是二叉樹。二叉樹的用處比較廣泛,用得最多的樹就是二叉樹。
二叉樹的每個結點最多有兩個子結點,左邊的一般稱為左孩子,右邊的稱為右孩子。根節點兩邊
的稱為左子樹和右子樹。二叉樹一般由遞迴的方法定義,所以處理二叉樹的方法基本上都由遞迴

來處理。要學好樹,必然的一定要對遞迴有一定的瞭解。

下面是我用C語言寫的一個二叉樹轉換為雙向連結串列的程式碼

#include <stdio.h>
#include <stdlib.h>

typedef struct tree
{
    int data;
    struct tree *l,*r;
}NODE;
NODE * create_node(int data)          //建立樹的新結點
{
    NODE *p = malloc(sizeof(NODE));
    p->data = data;
    p->l = p->r =NULL;
    return p;
}
NODE* create_tree(int i)       //建立一個簡易的二叉樹,這裡用遞迴
{
    NODE *root = create_node(i);
    if(2*i < 10)
	root->l = create_tree(2*i);
    if(2*i+1 < 10)
	root->r = create_tree(2*i+1);
    return root;
}
//將二叉樹變換成為雙向連結串列
NODE* tree_list(NODE *root,NODE** pHead,NODE **pTail)//pHead為總連結串列的頭指標,pTail為總連結串列的尾指標
{
    NODE *pHeadLeft,*pTailLeft,*pHeadRight,*pTailRight;//樹根左邊的連結串列的頭和尾以及右邊連結串列的頭和尾
    if( NULL == root )
    {
	*pHead = NULL;
	*pTail = NULL;
	return NULL;
    }
    if( NULL == root->l )
    {
	*pHead = root;
    }
    else
    {
	tree_list(root->l,&pHeadLeft,&pTailLeft);
        //這裡必須傳指標的地址,不然連結串列的指標pHeadLeft和pTailLeft的值不會改變
        *pHead = pHeadLeft;     //將總連結串列頭指向左子樹的連結串列頭
	root->l = pTailLeft;    //根節點的l指標指向左子樹的連結串列尾
	pTailLeft ->r = root;   //左子樹的連結串列尾的r指標指向根節點
    }

    if( NULL == root->r)
    {
	*pTail = root;
    }
    else
    {
        //與左子樹的相同,注意各個指標的指向
	tree_list(root->r,&pHeadRight,&pTailRight);
	*pTail = pTailRight;
	root->r = pHeadRight;
	pHeadRight->l = root;
    }
    return *pHead;
}
void show_tree(NODE *root)        //中序遍歷二叉樹
{
    if(NULL == root)
	return;
    show_tree(root->l);
    printf("%d-",root->data);
    show_tree(root->r);
}
void show_list(NODE *pHead)      //遍歷雙向連結串列
{
    NODE *p = pHead;
    while(p)
    {
	printf("%d-",p->data);
	p = p->r;
    }
    return ;
}
int main(int argc, char *argv[])
{               
    NODE *p = create_tree(1);   //建立一個二叉樹
    show_tree(p);               //中序遍歷
    puts("");

    NODE *l=NULL,*r=NULL;
    NODE* q = tree_list(p,&l,&r);  //將二叉樹轉換為雙向連結串列
    show_list(q);                  //遍歷連結串列
	return 0;
}


執行結果為
8-4-9-2-5-1-6-3-7-
8-4-9-2-5-1-6-3-7-


根據得到的結果可以看到,這種方法轉換出來的連結串列遍歷順序與二叉樹的中序遍歷得到的結果一樣
當然將二叉樹轉換為連結串列還有很多種方法,可以用 棧和佇列來處理。