树和二叉树相关算法(二) c/c++
1 //层次遍历算法 2 //顺序环形队列 3 typedef struct{ 4 BTNode *data[MaxSize]; 5 int front; 6 int rear; 7 }SqQueue; 8 9 void InitQueue(SqQueue *&qu) 10 { 11 qu = (SqQueue*)malloc(sizeof(SqQueue)); 12 qu->front = -1; 13 qu->rear = -1; 14 } 15 16 bool enQueue(SqQueue *&qu,BTNode *b) 17 { 18 if((qu->rear + 1) % MaxSize == qu->front) 19 return false; 20 qu->rear = (qu->rear + 1) % MaxSize; 21 qu->data[qu->rear] = b; 22 return true; 23 } 24 25 bool deQueue(SqQueue *&qu,BTNode *&b) 26 { 27 if(qu->front == qu->rear) 28 return false; 29 qu->front = (qu->front + 1) % MaxSize; 30 b = qu->data[qu->front]; 31 } 32 33 bool QueueEmpty(SqQueue *&qu) 34 { 35 return qu->front == qu->rear; 36 } 37 38 void LevelOrder(BTNode *b) 39 { 40 SqQueue *qu; 41 BTNode *p; 42 p = b; 43 InitQueue(qu); 44 enQueue(qu,p); 45 while(!QueueEmpty(qu)) 46 { 47 deQueue(qu,p); 48 cout<<p->data; 49 if(p->lchild != NULL) 50 enQueue(qu,p->lchild); 51 if(p->rchild != NULL) 52 enQueue(qu,p->rchild); 53 } 54 } 55 56 //用层次遍历输出根节点到所有叶子节点的路径(迷宫问题的思路) 57 //结点类型 58 typedef struct{ 59 BTNode *b; 60 int parent; //存放双亲结点在顺序队中的位置 61 }NodeType; 62 //顺序队 63 64 void AllPath2(BTNode *b) 65 { 66 NodeType Path[MaxSize]; //创建顺序队并初始化 67 int rear = -1;int front = -1; 68 NodeType p; 69 NodeType q; 70 71 p.b = b; 72 p.parent = -1; 73 Path[++rear] = p; 74 75 while(rear != front) 76 { 77 p = Path[++front]; 78 if(p.b->lchild == NULL && p.b->rchild == NULL) 79 { 80 int k = front; 81 while(Path[k].parent != -1) 82 { 83 cout<<Path[k].b->data; 84 k = Path[k].parent; 85 } 86 cout<<Path[k].b->data<<endl; 87 } 88 if(p.b->lchild != NULL) 89 { 90 q.b = p.b->lchild; 91 q.parent = front; 92 Path[++rear] = q; 93 } 94 if(p.b->rchild != NULL) 95 { 96 q.b = p.b->rchild; 97 q.parent = front; 98 Path[++rear] = q; 99 } 100 } 101 } 102 //先序序列和中序序列生成二叉树 103 BTNode *CreateBT1(char *pre,char *in,int n) 104 { 105 BTNode *b; 106 char *p; 107 int k; 108 109 if(n <= 0) 110 return NULL; 111 b = (BTNode *)malloc(sizeof(BTNode)); 112 for(p = in;p<in + n;p++) 113 { 114 if(*p == *pre) 115 break; 116 } 117 k = p - in; 118 b->data = *p; 119 b->lchild = CreateBT1(pre + 1,in,k); 120 b->rchild = CreateBT1(pre+k+1,p+1,n-k-1); 121 122 return b; 123 } 124 //后序序列和中序序列生成二叉树 125 BTNode *CreateBT2(char *in,char *post,int n) 126 { 127 BTNode *b; 128 char *p; 129 int k; 130 131 if(n <= 0) 132 return NULL; 133 b = (BTNode *)malloc(sizeof(BTNode)); 134 for(p = in;p < in + n; p++) 135 { 136 if(*p == *(post + n - 1)) 137 break; 138 } 139 k = p - in; 140 b->data = *p; 141 b->lchild = CreateBT2(in,post,k); 142 b->rchild = CreateBT2(in+k+1,post+k,n-k-1); 143 144 return b; 145 } 146 //二叉树顺序储存结构转换为链式储存结构 147 typedef ElemType SqBTree[MaxSize]; 148 BTNode *trans(SqBTree a,int i) 149 { 150 BTNode *b; 151 if(i > MaxSize) 152 return NULL; 153 if(a[i] == '#') 154 return NULL; 155 b = (BTNode *)malloc(sizeof(BTNode)); 156 b->data = a[i]; 157 b->lchild = trans(a,2*i); 158 b->rchild = trans(a,2*i+1); 159 160 return b; 161 } 162 163 //中序线索化二叉树 164 typedef struct tbtnode{ 165 ElemType data; 166 int ltag; 167 struct tbtnode *lchild; 168 struct tbtnode *rchild; 169 int rtag; 170 }TBTNode; 171 172 TBTNode *pre; 173 174 void Thread(TBTNode *&p) 175 { 176 if(p != NULL) 177 { 178 Thread(p->lchild); 179 if(p->lchild == NULL) 180 { 181 p->ltag = 1; 182 p->lchild = pre; 183 } 184 else 185 p->rtag = 0; 186 if(pre->rchild == NULL) 187 { 188 pre->rchild = p; 189 pre->rtag = 1; 190 } 191 else 192 pre->rtag = 0; 193 pre = p; 194 Thread(p->rchild); 195 } 196 } 197 198 TBTNode *CreateThread(TBTNode *b) 199 { 200 TBTNode *root; 201 root = (TBTNode *)malloc(sizeof(TBTNode)); 202 203 root->ltag = 0;root->rtag = 1; 204 root->rchild = b; 205 if(b == NULL) 206 root->lchild = root; 207 else 208 { 209 root->lchild = root; 210 pre = root; 211 Thread(b); 212 pre->rchild = root; 213 pre->rtag = 1; 214 root->rchild = pre; 215 } 216 return root; 217 } 218 219 //构造哈夫曼树 220 typedef struct{ 221 char data; 222 int parent; 223 int lchild; 224 int rchild; 225 double weight; 226 }HTNode; 227 228 void CreateHT(HTNode ht[],int n0) 229 { 230 int lnode,rnode; 231 double min1,min2; 232 for(int i = 0; i < 2*n0 - 2;i++) 233 ht[i].parent = ht[i].lchild = ht[i].rchild = -1; 234 for(int i = n0; i < 2*n0 - 2;i++) 235 { 236 min1 = min2 = 100000; 237 rnode = lnode = -1; 238 for(int k = 0; k < i ;k++) 239 { 240 if(ht[k].parent == -1) 241 { 242 if(ht[k].weight < min1) 243 { 244 min2 = min1;rnode = lnode; 245 min1 = ht[k].weight; 246 lnode = k; 247 } 248 else if(ht[k].weight < min2) 249 { 250 min2 = ht[k].weight; 251 rnode = k; 252 } 253 } 254 } 255 ht[lnode].parent = i; 256 ht[rnode].parent = i; 257 ht[i].lchild = lnode; 258 ht[i].rchild = rnode; 259 ht[i].weight = ht[lnode].weight + ht[rnode].weight; 260 } 261 } 262 263 //根据哈夫曼树求对应的哈夫曼编码 264 typedef struct 265 { 266 char cd[100]; 267 int start; 268 }HCode; 269 void CreateHCode(HTNode ht[],HCode hcd[],int n0) 270 { 271 int f,c; 272 HCode hc; 273 for(int i = 0;i < n0; i++) 274 { 275 hc.start = n0;c = i; 276 f = ht[i].parent; 277 while(f != -1) 278 { 279 if(ht[f].lchild == c) 280 hc.cd[hc.start--] = '0'; 281 else 282 hc.cd[hc.start--] = '1'; 283 c = f; f = ht[f].parent; 284 } 285 hc.start++; 286 hcd[i] = hc; 287 } 288 } 289 290 //用树实现并查集 291 //并查集节点类型 292 typedef struct{ 293 int data; 294 int parent; 295 int rank; 296 }UFSTree; 297 //初始化并查集 298 void MAKE_SET(UFSTree t[],int n) 299 { 300 for(int i=0; i<n; i++) 301 { 302 t[i].data = i; 303 t[i].parent = i; 304 t[i].rank = 0; 305 } 306 } 307 //查找一个元素所在的集合 308 int FIND_SET(UFSTree t[],int x) 309 { 310 if(x != t[x].parent) 311 return FIND_SET(t,t[x].parent); 312 else 313 return x; 314 } 315 //将两个元素所在的集合合并 316 void UNION(UFSTree t[],int x,int y) 317 { 318 x = FIND_SET(t,x); 319 y = FIND_SET(t,y); 320 if(t[x].rank > t[y].rank) 321 t[y].parent = x; 322 else 323 { 324 t[x].parent = y; 325 if(t[x].rank == t[y].rank) 326 t[y].rank++; 327 } 328 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统