1. 程式人生 > >FindKth(T,i)返回樹T的具有第i個最小關鍵字的元素。所有元素具有關鍵字互異的關鍵字。修改二叉樹以平均O(logN)時間支援這種運算

FindKth(T,i)返回樹T的具有第i個最小關鍵字的元素。所有元素具有關鍵字互異的關鍵字。修改二叉樹以平均O(logN)時間支援這種運算

資料結構與演算法分析——c語言描述 練習4.44 答案

用了以前的生成前N個自然數的一個隨機置換程式碼。

tree.h

typedef int ElementType;

#ifndef _Tree_H
#define _Tree_H

struct TreeNode;
typedef struct TreeNode *Position;
typedef struct TreeNode *SearchTree;

void makeEmpty(SearchTree t);
Position find(ElementType X, SearchTree t);
Position findMin(SearchTree t);
Position findMax(SearchTree t);
SearchTree insert(ElementType X, SearchTree t);
SearchTree Delete(ElementType X, SearchTree t);
ElementType Retrieve(Position p);
Position findKth(SearchTree t, int i);

#endif

tree.c
#include"tree.h"
#include"fatal.h"

struct TreeNode {
	ElementType element;
	SearchTree left;
	SearchTree right;
	int size;
};

void makeEmpty(SearchTree t) {
	if (t) {
		makeEmpty(t->left);
		makeEmpty(t->right);
		free(t);
	}
}

Position find(ElementType X, SearchTree t) {
	if (t == NULL)
		return NULL;//NOT FOUND
	else {
		if (X < t->element)
			return find(X, t->left);
		else if (X>t->element)
			return find(X, t->right);
		else
			return t;
	}
}

Position findMin(SearchTree t) {
	while (t->left)
		t = t->left;
	return t;
}

Position findMax(SearchTree t) {
	while (t->right)
		t = t->right;
	return t;
}

static size(SearchTree t) {
	if (t) {
		return t->size;
	}
	return 0;
}

SearchTree insert(ElementType X, SearchTree t) {
	if (t == NULL) {//包含樹沒有初始化
		t = malloc(sizeof(struct TreeNode));
		if (t == NULL)
			Error("out of memory");
		t->element = X;
		t->left = NULL;
		t->right = NULL;
		t->size = 1;
	}
	else {
		if (X < t->element)
			t->left = insert(X, t->left);
		else if (X>t->element)
			t->right = insert(X, t->right);
		t->size =	size(t->left) + size(t->right) + 1;
	}
	return t;//兩種情況
}

SearchTree Delete(ElementType X, SearchTree t) {
	Position tempCell;
	if (t == NULL) {
		Error("Element not found");
	}

	else if (X < t->element)
		t->left = Delete(X, t->left);
	else if (X > t->element)
		t->right = Delete(X, t->right);
	else if (t->left && t->right) {
		tempCell = findMin(t->right);
		t->element = tempCell->element;
		t->right = Delete(t->element, t->right);
	}
	else {
		tempCell = t;
		if (t->left == NULL)
			t = t->right;
		else if (t->right == NULL)
			t = t->left;
		free(tempCell);
	}
	if (t) {
		t->size = size(t->left) + size(t->right) + 1;
	}
	return t;
}

ElementType Retrieve(Position p) {
	return p->element;
}

Position findKth(SearchTree t, int i) {
	if (i <= size(t->left)) {
		return findKth(t->left, i);
	}
	else if (i == size(t->left) + 1)
		return t;
	else if (i <= t->size)
		return findKth(t->right, i -size(t->left) - 1);
	else
		return NULL;
}

main.c
#include<stdlib.h>
#include"tree.h"
#include<stdio.h>

struct TreeNode {
	ElementType element;
	SearchTree left;
	SearchTree right;
	int size;
};
void Dir(SearchTree t) {
	if (t) {
		printf("%d ", t->element);
		Dir(t->left);
		Dir(t->right);
	}
}



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 1208

int main() {

	SearchTree t1 = NULL;


	int a[N];

	getRandomInt(a, N);

	for (int i = 0; i < N; i++)
		t1 = insert(a[i], t1);


	printf("%d", findKth(t1, 135)->element);

}