栈,队列,堆,树

栈: 推荐由线性表实现。 

分为栈顶和栈底

栈的特点: 后进先出且只能从栈顶出数据

栈的结构

#define STData int

typedef struct STNode
{
	STData* arr;
	int size;
	int capacity;
}STNode;

接口

void STInit(STNode* st);

void STDestroy(STNode* st);

void STPush(STNode* st , STData x);

void STPop(STNode* st);

bool STEmpty(STNode* st);

STData STTop(STNode* st);

接口的实现

void STInit(STNode* st)
{
	st->arr = NULL;
	st->capacity = st->size = 0;
	return;
}

void STDestroy(STNode* st)
{
	assert(st);
	assert(!STEmpty(st));
	free(st->arr);
	st->arr = NULL;
	st->capacity = st->size = 0;
}

void STPush(STNode* st, STData x)
{
	assert(st);
	//不满
	if (st->size == st->capacity)
	{
		int newcapacity = st->capacity == 0 ? 4 : 2 * st->capacity;
		STData* arr = (STData*)realloc(st->arr, sizeof(STData) * newcapacity);
		if (arr == NULL)
		{
			perror("STPush::malloc(arr)");
			exit(1);
		}
		st->arr = arr;
		st->capacity = newcapacity;
	}
	st->arr[st->size++] = x;
}

void STPop(STNode* st)
{
	assert(st);
	assert(!STEmpty(st));

	st->size--;
}

bool STEmpty(STNode* st)
{
	assert(st);
	return st->size == 0;
}

STData STTop(STNode* st)
{
	assert(st);
	assert(!STEmpty(st));
	return st->arr[(st->size)-1];
}

int STSize(STNode* st)
{
	assert(st);
	assert(!STEmpty(st));
	return st->size;
}

队列:有队头和队尾

实现先进先出且只能从队头出数据

队列的结构

#define QData BTNode*

typedef struct QueNode
{
	QData val;
	struct QueNode* next;
}QNode;

typedef struct Queue
{
	//指向队头
	QNode* phead;
	//指向队尾
	QNode* ptail;
	int size;
}Queue;

接口

void QueueInit(Queue* pq);

void QueueDestroy(Queue* pq);

void QueuePush(Queue* pq, QData x);

void QueuePop(Queue* pq);

QData QueueFront(Queue* pq);

int QueueSize(Queue* pq);

bool QueueEmpty(Queue* pq);

QData QueueBack(Queue* pq);

接口的实现

void QueueInit(Queue* pq)
{
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}


void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* pn = pq->phead;
	while (pn)
	{
		pn = pq->phead->next;
		free(pq->phead);
		pq->phead = pn;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

void QueuePush(Queue* pq, QData x)
{
	assert(pq);
	QNode* qn = (QNode*)malloc(sizeof(QNode));
	if (qn == NULL)
	{
		perror("QueuePush::malloc(qn)");
		exit(1);
	}
	qn->val = x;
	qn->next = NULL;
	if (QueueEmpty(pq))
	{
		pq->phead = pq->ptail = qn;
	}
	else
	{
		pq->ptail->next = qn;
		pq->ptail = qn;
	}
	pq->size++;
}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	//只有一个节点的时候
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QNode* pn = pq->phead->next;
		free(pq->phead);
		pq->phead = pn;
	}
	pq->size--;
}

QData QueueFront(Queue* pq)
{
	return pq->phead->val;
}

int QueueSize(Queue* pq)
{
	return pq->size;
}

bool QueueEmpty(Queue* pq)
{
	return pq->size == 0;
}

QData QueueBack(Queue* pq)
{
	return pq->ptail->val;
}

堆: 实质上是线性表实现的一个二叉树结构

堆的结构

#define HPData int

typedef struct HPNode
{
	HPData* arr;
	int size;
	int capacity;
}HPNode;

接口(向上调整和向下调整在接口实现处包含)

void HPCreat(HPNode* hp, HPData* arr, int n);

void HPInit(HPNode* hp);

void HPDestroy(HPNode* hp);

void HPPush(HPNode* hp, HPData x);

void HPPop(HPNode* hp);

HPData HPTop(HPNode* hp);

bool HPEmpty(HPNode* hp);

int HPSize(HPNode* hp);

接口的实现

void swap(int* a, int* b)
{
	int s = *a;
	*a = *b;
	*b = s;
}

//向上调整
void AdjustUp(HPData* arr, int size)
{
	assert(arr);

	int child = size - 1;
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (arr[child] <= arr[parent])
		{
			swap(&arr[child], &arr[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
			break;
	}
}
//向下调整
void AdjustDown(HPData* arr, int size)
{
	assert(arr);

	int parent = 0;
	int child = parent * 2 + 1;
	while (child < size)
	{
		if (child + 1 < n && arr[child + 1] < arr[child])
		{
			child = child + 1;
		}
		if (arr[parent] >= arr[child])
		{
			swap(&arr[parent], &arr[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

void HPInit(HPNode* hp)
{
	hp->arr = NULL;
	hp->size = hp->capacity = 0;
}

void HPDestroy(HPNode* hp);

void HPPush(HPNode* hp, HPData x)
{
	assert(hp);
	
	//空间不足
	if (hp->size == hp->capacity)
	{
		int newcapacity = hp->capacity == 0 ? 4 : 2 * hp->capacity;
		HPData* arr = (HPData*)realloc(hp->arr,sizeof(HPData) * newcapacity);
		if (arr == NULL)
		{
			perror("HPPush::malloc(arr)");
			exit(1);
		}
		hp->arr = arr;
		hp->capacity = newcapacity;
	}
	hp->arr[hp->size++] = x;
	//向上调整
	int child = hp->size - 1;
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (hp->arr[child] <= hp->arr[parent])
		{
			swap(&hp->arr[child], &hp->arr[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

//堆的删除是删除根节点
void HPPop(HPNode* hp)
{
	assert(hp);
	assert(!HPEmpty(hp));
	swap(&hp->arr[0], &hp->arr[hp->size - 1]);
	hp->size--;
	AdjustDown(hp->arr, hp->size);
}

HPData HPTop(HPNode* hp)
{
	assert(hp);
	return hp->arr[0];
}

bool HPEmpty(HPNode* hp)
{
	assert(hp);
	return hp->size == 0;
}

int HPSize(HPNode* hp)
{
	return hp->size;
}

树: 此处是指二叉树。

二叉树的结构

#define BTData char

typedef struct BTNode
{
	BTData val;
	struct BTNode* left;//左孩子
	struct BTNode* right;//右孩子
}BTNode;

接口

BTNode* BTCreat(BTData* arr, int n, int* pi);

void BTDestroy(BTNode* root);

int BTSize(BTNode* root);

int BTLeafSize(BTNode* root);

int BTKLeafSize(BTNode* root , int k);

BTNode* BTFind(BTNode* root, BTData x);

void BTPrevOrder(BTNode* root);

void BTInOrder(BTNode* root);

void BTPostOrder(BTNode* root);

void BTLeveOrder(BTNode* root);

bool BTEmpty(BTNode* root);

接口的实现

// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BTCreat(BTData* arr, int n, int* pi)
{
	assert(arr);

	if (arr[*pi] == '#')
	{
		(*pi)++;
		return NULL;
	}

	BTNode* root = (BTNode*)malloc(sizeof(BTNode));
	if (root == NULL)
	{
		perror("BTCreat::malloc(root)");
		exit(1);
	}
	root->val = arr[(*pi)++];

	root->left = BTCreat(arr, n, pi);
	root->right = BTCreat(arr, n, pi);
	return root;
}

void BTDestroy(BTNode* root)
{
	Queue pq = { 0 };
	QueueInit(&pq);
	QueuePush(&pq, root);
	BTNode* bt = root;
	while (!QueueEmpty(&pq))
	{
		BTNode* bl = QueueFront(&pq);
		if (bl != NULL)
		{
			printf("%c ", bl->val);
			QueuePop(&pq);
			QueuePush(&pq, bt->left);
			QueuePush(&pq, bt->right);
			free(bt);
		}
		else
		{
			printf("# ");
			QueuePop(&pq);
		}
		if (!QueueEmpty(&pq))
			bt = QueueFront(&pq);
	}
}

int BTSize(BTNode* root)
{

	if (root == NULL)
		return 0;

	return BTSize(root->left) + BTSize(root->right) + 1;
}

int BTLeafSize(BTNode* root)
{
	if (root == NULL) return 0;

	if (root->left == NULL && root->right == NULL) return 1;

	return BTLeafSize(root->left) + BTLeafSize(root->right);
}

int BTKLeafSize(BTNode* root, int k)
{

	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}

	return BTKLeafSize(root->left, k - 1) + BTKLeafSize(root->right, k - 1);
}

BTNode* BTFind(BTNode* root, BTData x)
{
	if (root == NULL) return NULL;

	if (root->val == x) return root;
	else
	{
		BTNode* left = BTFind(root->left, x);
		BTNode* right = BTFind(root->right, x);
		if (left != NULL)
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}

void BTPrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("# ");
		return;
	}

	printf("%c ", root->val);
	BTPrevOrder(root->left);
	BTPrevOrder(root->right);
}

void BTInOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("# ");
		return;
	}

	BTPrevOrder(root->left);
	printf("%c ", root->val);
	BTPrevOrder(root->right);
}

void BTPostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("# ");
		return;
	}

	BTPrevOrder(root->left);
	BTPrevOrder(root->right);
	printf("%c ", root->val);
}

void BTLeveOrder(BTNode* root)
{
	Queue pq = { 0 };
	QueueInit(&pq);
	QueuePush(&pq, root);
	BTNode* bt = root;
	while (!QueueEmpty(&pq))
	{
		BTNode* bl = QueueFront(&pq);
		if (bl != NULL)
		{
			printf("%c ", bl->val);
			QueuePop(&pq);
			QueuePush(&pq, bt->left);
			QueuePush(&pq, bt->right);
		}
		else
		{
			printf("# ");
			QueuePop(&pq);
		}
		if(!QueueEmpty(&pq))
			bt = QueueFront(&pq);
	}
}

bool BTEmpty(BTNode* root)
{
	return root == NULL;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值