线索树

数据结构与算法分析——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);
}


你可能感兴趣的:(线索树)