樹和二叉樹的存儲結構的實現(C/C++實現)


存檔:

 1 #include <iostream.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #define max 20
 5 typedef char elemtype;
 6 #include "tree.h"
 7 void main()
 8 {
 9     btree t,p;
10     char x;
11     int i=0,num=0;
12     cout<<"(1)初始化二叉樹initbt(t):"<<endl;
13     initbt(t);
14     cout<<"(2)輸入先序遍歷序列,創建二叉樹(空樹以#表示)createbt(t):"<<endl;
15     createbt(t);
16     cout<<"判斷二叉樹是否為空樹emptybt(t):";
17     i=emptybt(t);
18     if(i==1)
19         cout<<"二叉樹為空樹!"<<endl;
20     else
21         cout<<"二叉樹非空!"<<endl;
22     cout<<"(4)輸出二叉樹的括號描述displaybt(t):";
23     displaybt(t);
24     cout<<endl;
25     cout<<"(5)二叉樹的深度depthbt(t)為:"<<depthbt(t)<<endl;
26     cout<<"(6)二叉樹的葉子結點的個數leafcount(t,num)為:";
27     leafcount(t,num);
28     cout<<num<<endl;
29     cout<<"(7)二叉樹的結點總個數nodecount(t)為:"<<nodecount(t)<<endl;
30     cout<<"(8)先序遍歷preorder(t)的結果為:";
31     preorder(t);
32     cout<<endl;
33     cout<<"(9)中序遍歷inorder(t)的結果為:";
34     inorder(t);
35     cout<<endl;
36     cout<<"(10)后序遍歷postorder(t)的結果為:";
37     postorder(t);
38     cout<<endl;
39     cout<<"(11)層次遍歷levelorder(t)的結果為:";
40     levelorder(t);
41     cout<<endl;
42     fflush(stdin);//清空緩存
43     cout<<"(12)輸入一個字符,並在樹中查找該字符是否存在findnode(t,x):";
44     cin>>x;
45     if(findnode(t,x))
46         cout<<"字符存在!";
47     else 
48         cout<<"字符不存在!";
49     cout<<endl;
50     cout<<"(13)字符"<<x<<"對應結點findnode1(t,x)的孩子為:"<<endl;
51     p=findnode1(t,x);
52     if(p!=NULL)
53     {
54         if(p->lchild!=NULL)
55             cout<<x<<"左孩子為:"<<p->lchild->data<<" ";
56         else
57             cout<<x<<"無左孩子"<<" ";
58         if(p->rchild!=NULL)
59             cout<<x<<"右孩子為:"<<p->rchild->data<<endl;
60         else
61             cout<<x<<"無右孩子"<<endl;
62     }
63     else
64         cout<<x<<"不存在"<<endl;
65     cout<<"(14)清空clearbt(t)的結果為:";
66     clearbt(t);
67     if(emptybt(t))
68         cout<<"二叉樹為空樹!"<<endl;
69     else
70         cout<<"二叉樹非空!"<<endl;
71     cout<<"(15)按照二叉樹的括號描述createbt1(t,str)創建二叉樹A(B(D,E),C(,F))";
72     createbt1(t,"A(B(D,E),C(,F))");
73     cout<<endl;
74     cout<<"輸出二叉樹的括號描述displaybt(t):";
75     displaybt(t);
76     cout<<endl;
77     cout<<"先序遍歷preorder(t)的結果為:";
78     preorder(t);
79     cout<<endl;
80     cout<<"中序遍歷inorder(t)的結果為:";
81     inorder(t);
82     cout<<endl;
83     clearbt(t);
84     system("pause");
85 }
  1 struct node
  2 {
  3     elemtype data;//數據元素
  4     struct node *lchild;//指向左孩子
  5     struct node *rchild;//指向右孩子
  6 };
  7 typedef struct node btnode;//定義結構體的別名btnode
  8 typedef struct node *btree;//定義結構體指針的別名btree
  9 void initbt(btree &t)//初始化函數,構造一棵空樹
 10 {
 11     t=NULL;
 12 }
 13 void createbt(btree &t)//先序遍歷序列創建二叉樹
 14 {
 15     elemtype ch;
 16     cin>>ch;
 17     if(ch=='#')
 18         t=NULL;//#表示空樹,遞歸終止
 19     else
 20     {
 21         t=new btnode;//創建新結點
 22         if(t==NULL)//如果創建結點失敗,就退出
 23             exit(-2);
 24         t->data=ch;//生成根結點
 25         createbt(t->lchild);//構造左子樹
 26         createbt(t->rchild);//構造右子樹
 27     }
 28 }
 29 int emptybt(btree t)//判斷樹是否為空樹
 30 {
 31     if(t==NULL)
 32         return 1;//空樹返回1
 33     else 
 34         return 0;//非空樹返回0
 35 }
 36 int depthbt(btree t)//求二叉樹t的深度
 37 {
 38     if(t==NULL)
 39         return 0;//空樹深度為0
 40     else 
 41     {
 42         int depthl=depthbt(t->lchild);//求左子樹的高度為depthl
 43         int depthr=depthbt(t->rchild);//求右子樹的高度為depthr
 44         return 1+(depthl>depthr?depthl:depthr);//子樹深度最大的+1
 45     }
 46 }
 47 int findnode(btree t,elemtype x)//仿照先序遍歷,查找data域為x的結點是否存在
 48 {
 49     int i;
 50     if(t==NULL)
 51         return 0;//t為空樹,無結點,不存在x,返回0
 52     else if(t->data==x)//t結點恰好是x對應結點,返回1
 53         return 1;
 54     else
 55     {
 56         i=findnode(t->lchild,x);//在左子樹中去查找x
 57         if(i!=0)//如果找到了就返回
 58             return i;
 59         else 
 60             return findnode(t->rchild,x);//沒找到就去右子樹中查找x
 61     }
 62 }
 63 btree findnode1(btree t,elemtype x)//仿照先序遍歷,查找data域為x的結點,返回結點指針
 64 {
 65     btree p;
 66     if(t==NULL)
 67         return NULL;//t為空樹,不存在x,返回NULL
 68     else if(t->data==x)//t結點恰好是x對應結點,返回t
 69         return t;
 70     else
 71     {
 72         p=findnode1(t->lchild,x);//在左子樹中去查找x
 73         if(p!=NULL)//如果找到了就返回
 74             return p;
 75         else 
 76             return findnode1(t->rchild,x);//沒找到就去右子樹中查找x
 77     }
 78 }
 79 void preorder(btree t)//先序遍歷的遞歸算法
 80 {
 81     if(t!=NULL)
 82     {
 83         cout<<t->data<<' ';//訪問根結點
 84         preorder(t->lchild);//遞歸訪問左子樹
 85         preorder(t->rchild);//遞歸訪問右子樹
 86     }
 87 }
 88 void inorder(btree t)//中序遍歷的遞歸算法
 89 {
 90     if(t!=NULL)
 91     {
 92         inorder(t->lchild);//遞歸訪問左子樹
 93         cout<<t->data<<' ';//訪問根結點
 94         inorder(t->rchild);//遞歸訪問右子樹
 95     }
 96 }
 97 void postorder(btree t)//后序遍歷的遞歸算法
 98 {
 99     if(t!=NULL)
100     {
101         postorder(t->lchild);//遞歸訪問左子樹
102         postorder(t->rchild);//遞歸訪問右子樹
103         cout<<t->data<<' ';//訪問根結點
104     }
105 }
106 void clearbt(btree &t)//仿照后序遍歷的遞歸算法
107 {
108     if(t!=NULL)
109     {
110         clearbt(t->lchild);//先清空左子樹
111         clearbt(t->rchild);//后清空右子樹
112         delete t;//刪除根結點
113         t=NULL;
114     }
115 }
116 void levelorder(btree t)//借助循環隊列的原理,實現層次遍歷
117 {
118     btree queue[max];//定義循環隊列
119     int front,rear;//定義隊首和隊尾指針
120     front=rear=0;//置隊列為空隊列
121     if(t!=NULL)
122         cout<<t->data<<' ';//先訪問再入隊列
123     queue[rear]=t;
124     rear++;//結點指針入隊列
125     while(rear!=front)//隊列不為空,繼續循環
126     {
127         t=queue[front];//隊頭出隊列
128         front=(front+1)%max;
129         if(t->lchild!=NULL)//輸出左孩子,並入隊列
130         {
131             cout<<t->lchild->data<<' ';
132             queue[rear]=t->lchild;
133             rear=(rear+1)%max;
134         }
135         if(t->rchild!=NULL)//輸出右孩子,並入隊列
136         {
137             cout<<t->rchild->data<<' ';
138             queue[rear]=t->rchild;
139             rear=(rear+1)%max;
140         }
141     }
142 }
143 int nodecount(btree t)//求二叉樹t的結點個數
144 {
145     int num1,num2;
146     if(t==NULL)
147         return 0;//空樹結點個數為0
148     else
149     {
150         num1=nodecount(t->lchild);//左子樹結點個數
151         num2=nodecount(t->rchild);//右子樹結點個數
152         return (num1+num2+1);//左子樹+右子樹+1
153     }
154 }
155 void leafcount(btree t,int &count)//求二叉樹t的葉子結點的個數
156 {
157     if(t!=NULL)
158     {
159         if(t->lchild==NULL&&t->rchild==NULL)
160             count++;//葉子結點計算
161         leafcount(t->lchild,count);//左子樹葉子個數
162         leafcount(t->rchild,count);//右子樹葉子個數
163     }
164 }
165 void displaybt(btree t)//以廣義表法輸出二叉樹
166 {
167     if(t!=NULL)
168     {
169         cout<<t->data;
170         if(t->lchild!=NULL||t->rchild!=NULL)
171         {
172             cout<<'(';
173             displaybt(t->lchild);
174             if(t->rchild!=NULL)
175                 cout<<',';
176             displaybt(t->rchild);
177             cout<<')';
178         }
179     }
180 }
181 void createbt1(btree &t,char *str)//由廣義表str串創建二叉鏈
182 {
183     btnode *st[max];
184     btnode *p=NULL;
185     int top=-1,k,j=0;
186     char ch;
187     t=NULL;//建立的二叉樹初始化為空
188     ch=str[j];
189     while(ch!='\0')//str未掃描完時循環
190     {
191         switch(ch)
192         {
193             case '(':top++;st[top]=p;k=1;break;//為左結點
194             case ')':top--;break;
195             case ',':k=2;break;//為右結點
196             default:p=new btnode;
197             p->data=ch;
198             p->lchild=p->rchild=NULL;
199             if(t==NULL)//p指向二叉樹的根結點
200                 t=p;
201             else//已建立二叉樹根結點
202             {
203                 switch(k)
204                 {
205                     case 1:st[top]->lchild=p;break;
206                     case 2:st[top]->rchild=p;break;
207                 }
208             }
209         }
210         j++;
211         ch=str[j];
212     }
213 }

運行結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM