程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 數據結構之---C語言實現線索二叉樹

數據結構之---C語言實現線索二叉樹

編輯:關於C語言

數據結構之---C語言實現線索二叉樹


//線索二叉樹,這裡在二叉樹的基礎上添加了線索化
//楊鑫
#include 
#include 
typedef char ElemType; 					
typedef enum {Link,Thread} childTag; 	//Link表示結點,Thread表示線索
typedef struct bitNode
{
  ElemType data;
  struct bitNode *lchild, *rchild;
  int ltag, rtag;
} bitNode, *bitTree;

bitTree pre; 							//創建全局變量,表示剛剛訪問過的結點



/*
創建二叉樹,其輸入必須按照前序遍歷的次序。
T:二叉樹根節點
arr:按照前序遍歷次序排列的各節點的值。無孩子結點時用空格代替
*/
void create_tree(bitTree *T, char **arr)
{
  char c;
  sscanf(*arr,"%c",&c); 						//讀入一個結點值
  (*arr)++;
  if(' '== c) 									//如果是空格,表示空結點
    {
      *T=NULL;
    }
  else 
    {
      *T=(bitTree)malloc(sizeof(bitNode)); 		//構造新結點
      (*T)->data=c;
      (*T)->ltag=Link;
      (*T)->rtag=Link;
      create_tree(&(*T)->lchild,arr);			//構造新結點的左孩子
      create_tree(&(*T)->rchild,arr);			//構造新結點的右孩子
    }
}


/*
訪問結點信息
*/
void visit(bitTree T)
{
    printf("| %d | %c | %d |\n",T->ltag,T->data,T->rtag);
}


/*
前序遍歷訪問二叉樹
*/
void pre_order_traverse(bitTree T,int level)
{
  if(T)
    {
      visit(T);
      pre_order_traverse(T->lchild,level+1);
      pre_order_traverse(T->rchild,level+1);
    }
}

/*
中序遍歷二叉樹,對其進行線索化
*/
void in_order_threading(bitTree T)
{
  if(T)
    {
      in_order_threading(T->lchild); 			//左孩子線索化
      if(!T->lchild) 							//如果左孩子為空,則將其指向直接前驅
    {
      T->lchild=pre;
      T->ltag=Thread;
    }
      if(!pre->rchild) 							//如果上一個結點的右孩子為空,則將其指向直接後繼。(注意:只有訪問到下一個結點時,才會知道本結點的後繼是誰)
    {
      pre->rchild=T;
      pre->rtag=Thread;
    }
      pre=T;
      in_order_threading(T->rchild); 			//右孩子線索化
    }
}

/*
加入一個頭結點,使二叉線索樹成一個封閉環
P:帶有頭結點的二叉樹。頭結點的左孩子指向二叉樹T;右孩子指向T樹中的最後一個葉子結點
T:不帶有頭結點的二叉樹。
*/
void in_thread(bitTree *P,bitTree T)
{
  (*P)=(bitTree)malloc(sizeof(bitNode)); 		//構造新加入的頭結點
  (*P)->ltag=Link;
  (*P)->rtag=Thread;
  (*P)->rchild=*P;
  if(!T) 										//如果二叉樹為空,則P的孩子指向自己。
    {
      (*P)->lchild=*P;
    }
  else
    {
      (*P)->lchild=T;
      pre=*P;
      in_order_threading(T); 					//對二叉樹進行線索化
      (*P)->rchild=pre; 						//將頭結點右孩子指向最後一個葉子結點
      pre->rtag=Thread; 						//將最後一個葉子結點的右孩子指向頭結點。這樣,環就形成了。
      pre->rchild=*P;
    }
}

/*
非遞歸方式:中序遍歷二叉樹(樹必須帶有頭結點,且已經線索化)
P:帶有頭結點的二叉樹
*/
void in_order_traverse(bitTree P)
{
  bitTree T;
  T=P->lchild;
  while(T!=P) 									//判斷是否空樹
    {
      while(T->ltag==Link) 						//從左孩子開始,直到葉子結點
		{
		  T=T->lchild;
		}
      visit(T);
      while(T->rtag==Thread && T->rchild!=P) //根據線索,訪問後繼結點。並且後繼結點不是指向頭結點的
		{
		  T=T->rchild;
		  visit(T);
		}
      T=T->rchild;
    }
}


int main()
{
  bitTree P,T;
  int level =1; 					//表示該結點的深度
  char *arr="ab d  ce   "; 			//構造二叉樹所需結點(按前序遍歷方式輸入)
  create_tree(&T,&arr); 			//構造二叉樹
  printf("pre_order_traverse:先序遍歷:\n");
  pre_order_traverse(T,level); 		//前序遍歷輸出二叉樹
  printf("in_order_traverse:中序遍歷:\n");
  in_thread(&P,T); 					//二叉樹線索化
  in_order_traverse(P); 			//輸出線索化後的二叉樹
  return 0;
}

 

如圖:

 

\

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved