数据结构与算法分析——c语言描述 练习4.45 答案
这道题作者只说了线索树是什么,没给思路,插入删除完全靠自己写出来。中缀遍历有点意思,网上大概看了看代码。
threadedtree.h
typedef int ElementType; #ifndef _Tree_H #define _Tree_H struct TreeNode; typedef struct TreeNode *Position; typedef struct TreeNode *ThreadedTree; void makeEmpty(ThreadedTree t); Position find(ElementType X, ThreadedTree t); Position findMin(ThreadedTree t); Position findMax(ThreadedTree t); ThreadedTree insert(ElementType X, ThreadedTree t); ThreadedTree Delete(ElementType X, ThreadedTree t); ElementType Retrieve(Position p); void inOrderTraverse(ThreadedTree t); #endif
threadedtree.c
#include"threadedtree.h" #include"fatal.h" enum PointTag { link, thread }; static ThreadedTree threadOfDeleteNode; static int sonBranch;//0为左,1为右 struct TreeNode { ElementType element; ThreadedTree left; ThreadedTree right; enum PointTag ltag; enum PointTag rtag; }; void makeEmpty(ThreadedTree t) { if (t) { makeEmpty(t->left); makeEmpty(t->right); free(t); } } Position find(ElementType X, ThreadedTree t) { if (t == NULL) return NULL;//NOT FOUND else { if (X < t->element && t->ltag == link) return find(X, t->left); else if (X > t->element && t->rtag == link) return find(X, t->right); else return t; } } Position findMin(ThreadedTree t) { while (t->left && t->ltag == link) t = t->left; return t; } Position findMax(ThreadedTree t) { while (t->right && t->rtag == link) t = t->right; return t; } ThreadedTree insert(ElementType X, ThreadedTree t) { if (t == NULL) {//包含树没有初始化 t = malloc(sizeof(struct TreeNode)); if (t == NULL) Error("out of memory"); t->element = X; t->left = NULL; t->ltag = thread; t->right = NULL; t->rtag = thread; } else if (X < t->element) { if (t->ltag == link) t->left = insert(X, t->left); else {//ltag=thread Position inorderPredecessor = t->left; t->left = insert(X, NULL); t->left->left = inorderPredecessor; t->left->right = t; t->ltag = link; } } else if (X > t->element) { if (t->rtag == link) t->right = insert(X, t->right); else {//ltag=thread Position inorderSuccessor = t->right; t->right = insert(X, NULL); t->right->left = t; t->right->right = inorderSuccessor; t->rtag = link; } } return t;//两种情况 } ThreadedTree Delete(ElementType X, ThreadedTree t) { Position tempCell; if (t == NULL) { Error("Element not found"); } else if (X < t->element) { if (t->ltag == link) { sonBranch = 0; t->left = Delete(X, t->left); if (t->left == NULL) { t->ltag = thread; t->left = threadOfDeleteNode; } } else Error("Element not found "); } else if (X > t->element) { if (t->rtag == link) { sonBranch = 1; t->right = Delete(X, t->right); if (t->right == NULL) { t->rtag = thread; t->right = threadOfDeleteNode; } else Error("Element not found"); } } else if (t->ltag == link && t->rtag == link) {//两个儿子 tempCell = findMin(t->right); t->element = tempCell->element; sonBranch = 1; t->right = Delete(t->element, t->right); if (t->right == NULL) { t->rtag = thread; t->right = threadOfDeleteNode; } } else if (t->ltag == thread && t->rtag == thread) {//无儿子 tempCell = t; if (sonBranch == 0) threadOfDeleteNode = t->left; else threadOfDeleteNode = t->right; free(tempCell); t = NULL; } else {//一个儿子 tempCell = t; if (t->ltag == link) {//左边为儿子 Position theLastVisitOfLeftSubTree = t->left; threadOfDeleteNode = t->right; t = t->left;//新根 while (theLastVisitOfLeftSubTree->rtag==link) theLastVisitOfLeftSubTree = theLastVisitOfLeftSubTree->right; theLastVisitOfLeftSubTree->right = threadOfDeleteNode; } else { Position theFirstVisitOfLeftSubTree = t->right; threadOfDeleteNode = t->left; t = t->right; while (theFirstVisitOfLeftSubTree->ltag==link) theFirstVisitOfLeftSubTree = theFirstVisitOfLeftSubTree->left; theFirstVisitOfLeftSubTree->left = threadOfDeleteNode; } } return t; } ElementType Retrieve(Position p) { return p->element; } void inOrderTraverse(ThreadedTree t) { ThreadedTree root = t; while (t) { while (t->ltag == link) { t = t->left; } printf("%d ", t->element); while (t->rtag == thread && t->right) { t = t->right; printf("%d ", t->element); } t = t->right; } }
main.c
#include"threadedtree.h" #include<stdio.h> #include<stdlib.h> int RandInt(int i, int j) { int temp; temp = (int)(i + (1.0*rand() / RAND_MAX)*(j - i)); return temp; } void getRandomInt(int *A, int n) { for (int i = 0; i < n; i++) { A[i] = i + 1; } for (int i = 1; i < n; i++) { //std::swap(A[i], A[RandInt(0, i)]); int randAdrr = RandInt(0, i); int t = A[i]; A[i] = A[randAdrr]; A[randAdrr] = t; } } #define N 56 int main() { int a[N]; ThreadedTree t= NULL; getRandomInt(a, N); for (int i = 0; i < N; i++) { t = insert(a[i], t); } inOrderTraverse(t); printf("\n"); printf("\n"); printf("\n"); for (int i = 1; i <= N / 2; i++) t = Delete(i, t); inOrderTraverse(t); }