数据结构C语言实现

1. 简介

数据结构的C语言实现版本,主要针对大学教材《数据结构(C语言版)》(严版数据结构)中的伪代码加以实现

代码仓库:数据结构总结: C语言版实现"数据结构(严版)"中的部分数据结构及算法,仅供参考 包括:顺序表、链表、栈、队列、串、二叉树 (gitee.com)

2. 架构

所有数据结构及算法均以C语言实现

3. 代码

代码采用模块化管理:

test.c为测试文件,用以测试数据结构及其算法

DataStructure.h为入口文件,集成各个数据结构模块

Data.h用以定义模拟数据

各个数据结构文件用以实现各个数据结构的存储与操作

  • DataStructure.h
// 数据结构头文件
#pragma once

// 文件引入
#include "Data.h"
#include "SqList.h"
#include "LinkedList.h"
#include "Stack.h"	
#include "Queue.h"
#include "BiTree.h"
  • Data.h
#pragma once

// 定义结构体数据
#define STRLEN_MAX 10
typedef struct Data
{
	int num;
	char string[STRLEN_MAX];
}Data;

// 定义状态值 
#define OK 1
#define ERROR 0
typedef int Status;

1. 顺序表
  • SqList.h
#pragma once
#include "Data.h"

// 定义顺序表
#define APPAND_SIZE 10
typedef struct SqList
{
	Data* base;
	int curLen;
	int maxLen;
}SqList;

/// <summary>
/// 打印顺序表元素(回调函数)
/// </summary>
/// <param name="data">数据元素</param>
void Print_SqList(Data* data);

/// <summary>
/// 比较元素(回调函数)
/// </summary>
/// <param name="d1">第一个元素</param>
/// <param name="d2">第二个元素</param>
/// <returns>比较结果</returns>
int Cmp_SqList(Data* d1, Data* d2);

/// <summary>
/// 初始化顺序表
/// </summary>
/// <param name="len">顺序表的最大长度</param>
/// <returns>已初始化的顺序表地址</returns>
SqList* InitSqList(int len);

/// <summary>
/// 判断顺序表是否为空
/// </summary>
/// <param name="list">顺序表指针</param>
/// <returns>判断结果</returns>
int IsSqListEmpty(const SqList* list);

/// <summary>
/// 判断顺序表是否为满
/// </summary>
/// <param name="list">顺序表指针</param>
/// <returns>判断结果</returns>
int IsSqListFull(const SqList* list);

/// <summary>
/// 获取顺序表的长度
/// </summary>
/// <param name="list">顺序表指针</param>
/// <returns>顺序表长度</returns>
int GetSqListLength(const SqList* list);

/// <summary>
/// 在顺序表末尾增添一个元素
/// </summary>
/// <param name="list">顺序表指针</param>
/// <param name="data">新增数据指针</param>
/// <returns>状态码</returns>
Status AppendSqList(SqList* list, Data* data);

/// <summary>
/// 遍历顺序表
/// </summary>
/// <param name="list">顺序表指针</param>
/// <param name="cb">回调函数</param>
void TraveseSqList(SqList* list, void(*cb)(Data*));

/// <summary>
/// 在顺序表末尾删除一个元素
/// </summary>
/// <param name="list">顺序表指针</param>
/// <param name="data">新增数据指针</param>
/// <returns>状态码</returns>
Status PopSqList(SqList* list, Data* data);

/// <summary>
/// 在顺序表中插入元素
/// </summary>
/// <param name="list">顺序表指针</param>
/// <param name="data">新增数据指针</param>
/// <param name="pos">插入位置</param>
/// <returns>状态码</returns>
Status InsertSqList(SqList* list, Data* data, int pos);

/// <summary>
/// 在顺序表中删除元素
/// </summary>
/// <param name="list">顺序表指针</param>
/// <param name="data">新增数据指针</param>
/// <param name="pos">删除位置</param>
/// <returns>状态码</returns>
Status RemoveSqList(SqList* list, Data* data, int pos);

/// <summary>
/// 翻转顺序表
/// </summary>
/// <param name="list">顺序表指针</param>
void ReverseSqList(SqList* list);

/// <summary>
/// 顺序表冒泡排序
/// </summary>
/// <param name="list">顺序表指针</param>
/// <param name="cmp">比较回调函数</param>
void BubbleSort_SqList(SqList* list, int(*cmp)(Data*, Data*));

/// <summary>
/// 清空顺序表
/// </summary>
/// <param name="list">顺序表指针</param>
void ClaerSqList(SqList* list);

/// <summary>
/// 删除顺序表
/// </summary>
/// <param name="list">顺序表的二级指针</param>
void DeleteSqList(SqList** list);
  • SqList.c
// SqList
#define _CRT_SECURE_NO_WARNINGS

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "Data.h"
#include "SqList.h"

// ---------- CALLBACK ----------
void Print_SqList(Data* data)
{
	printf("num = %d  string = %s\n", data->num, data->string);
}

int Cmp_SqList(Data* d1, Data* d2)
{
	return d1->num - d2->num;
}

// ---------- MAIN ----------
SqList* InitSqList(int len)
{
	SqList* list = (SqList*)malloc(sizeof(SqList));
	if (list)
	{
		if (len < 0) return NULL;
		list->base = (Data*)malloc(sizeof(Data) * len);
		if (list->base)
		{
			list->curLen = 0;
			list->maxLen = len;
			return list;
		}
		else
		{
			free(list);
			exit(-1);
			return NULL;
		}
	}
	else
	{
		exit(-1);
		return NULL;
	}
}

int IsSqListEmpty(const SqList* list)
{
	return !(list->curLen);
}

int IsSqListFull(const SqList* list)
{
	return list->curLen == list->maxLen;
}

static Status ExpandSqList(SqList* list, int size)
{
	if (size < list->maxLen) return ERROR;
	Data* tmp = (Data*)realloc(list->base, sizeof(Data) * (size + list->maxLen));
	if (tmp)
	{
		list->base = tmp;
		list->maxLen = size + list->maxLen;
		return OK;
	}
	else
	{
		exit(-1);
		return ERROR;
	}
}

int GetSqListLength(const SqList* list)
{
	return list->curLen;
}

Status AppendSqList(SqList* list, Data* data)
{
	if (IsSqListFull(list))
	{
		// 扩容
		if (ExpandSqList(list, APPAND_SIZE) == ERROR)
		{
			exit(-1);
			return ERROR;
		}
	}
	memcpy(list->base + list->curLen, data, sizeof(Data));
	list->curLen++;
	return OK;
}

void TraveseSqList(SqList* list, void(*cb)(Data*))
{
	for (int i = 0; i < list->curLen; i++)
	{
		cb(list->base + i);
	}
}

Status PopSqList(SqList* list, Data* data)
{
	if (IsSqListEmpty(list))
	{
		return ERROR;
	}
	else
	{
		memcpy(data, list->base + list->curLen - 1, sizeof(Data));
		list->curLen--;
		return OK;
	}
}

Status InsertSqList(SqList* list, Data* data, int pos)
{
	if (IsSqListFull(list))
	{
		// 扩容
		ExpandSqList(list, APPAND_SIZE);
	}

	// 移动
	for (int i = list->curLen; i >= pos; i--)
	{
		memcpy(list->base + i, list->base + i - 1, sizeof(Data));
	}
	// 插入
	memcpy(list->base + pos - 1, data, sizeof(Data));
	// 长度+1
	list->curLen++;

	return OK;
}

Status RemoveSqList(SqList* list, Data* data, int pos)
{
	if (IsSqListEmpty(list))
	{
		return ERROR;
	}
	else
	{
		memcpy(data, list->base + pos - 1, sizeof(Data));
		for (int i = pos; i <= list->curLen; i++)
		{
			memcpy(list->base + i - 1, list->base + i, sizeof(Data));
		}
		list->curLen--;

		return OK;
	}
}

void ReverseSqList(SqList* list)
{
	int left = 0;
	int right = list->curLen - 1;
	Data tmp = { 0 };
	while (left < right)
	{
		memcpy(&tmp, list->base + left, sizeof(Data));
		memcpy(list->base + left, list->base + right, sizeof(Data));
		memcpy(list->base + right, &tmp, sizeof(Data));
		left++;
		right--;
	}
}

void BubbleSort_SqList(SqList* list, int(*cmp)(Data*, Data*))
{
	Data tmp = { 0 };
	for (int i = list->curLen - 1; i > 0; i--)
	{
		for (int j = 0; j < i; j++)
		{
			if (cmp(list->base + j, list->base + j + 1) > 0)
			{
				memcpy(&tmp, list->base + j, sizeof(Data));
				memcpy(list->base + j, list->base + j + 1, sizeof(Data));
				memcpy(list->base + j + 1, &tmp, sizeof(Data));
			}
		}
	}
}

void ClaerSqList(SqList* list)
{
	free(list->base);
	list->curLen = 0;
	list->base = NULL;
}

void DeleteSqList(SqList** list)
{
	if ((*list)->base)  ClaerSqList(*list);
	*list = NULL;
}
2. 链表
  • LinkedList.h
#pragma once
#include "Data.h"

// 定义单链表
typedef struct LNode
{
	Data data;
	struct LNode* next;
}LNode, * LinkedList;

// 定义双向链表
typedef struct DuLNode
{
	Data data;
	struct DuLNode* next;
	struct DuLNode* prior;
}DuLNode, * DuLinkedList;

// ********************** 单链表 **********************

// ---------- CALLBACK ----------
void Print_LinkedList(LNode* p);

// ---------- MAIN ----------
/// <summary>
/// 初始化链表
/// </summary>
/// <returns>已初始化的链表地址</returns>
LinkedList InitLinkedList();

/// <summary>
/// 判断链表是否为空
/// </summary>
/// <param name="list">链表头结点</param>
/// <returns>判断结果</returns>
int IsLinkedListEmpty(const LinkedList list);

/// <summary>
/// 获取链表长度
/// </summary>
/// <param name="list">链表头结点</param>
/// <returns>链表长度</returns>
int GetLinkedListLength(const LinkedList list);

/// <summary>
/// 定位链表元素
/// </summary>
/// <param name="list">链表头结点</param>
/// <param name="pos">待获取的结点位置</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status LocateLinkedList(const LinkedList list, int pos, Data* data);

/// <summary>
/// 在链表中插入元素
/// </summary>
/// <param name="list">链表头结点</param>
/// <param name="pos">插入位置</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status InsertLinkedList(LinkedList list, int pos, Data* data);

/// <summary>
/// 遍历链表
/// </summary>
/// <param name="list">链表头结点</param>
/// <param name="cb">回调函数</param>
void TraveseLinkedList(LinkedList list, void(*cb)(LNode*));

/// <summary>
/// 在链表中删除元素
/// </summary>
/// <param name="list">链表头结点</param>
/// <param name="pos">删除位置</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status RemoveLinkedList(LinkedList list, int pos, Data* data);

/// <summary>
/// 删除链表
/// </summary>
/// <param name="list">链表的二级指针</param>
void DeleteLinkedList(LinkedList* list);

/// <summary>
/// 合并链表,将链表2合并至链表1
/// </summary>
/// <param name="list1">链表1</param>
/// <param name="list2">链表2</param>
void MergeLinkedList(LinkedList list1, LinkedList list2);

// ********************************************

// ********************** 双向链表 **********************

// ------------ CALLBACK ------------
void Print_DuLinkedList(DuLNode* p);

// ----------- MAIN -----------
/// <summary>
/// 初始化双向链表
/// </summary>
/// <returns>已初始化双向链表的地址</returns>
DuLinkedList InitDuLinkedList();

/// <summary>
/// 遍历双向链表
/// </summary>
/// <param name="list">双向链表头结点</param>
/// <param name="cb">回调函数</param>
void TraveseDuLinkedList(DuLinkedList list, void(*cb)(DuLNode*));

/// <summary>
/// 判断双向链表是否为空
/// </summary>
/// <param name="list">双向链表头结点</param>
/// <returns>判断结果</returns>
int IsDuLinkedListEmpty(const DuLinkedList list);

/// <summary>
/// 双向链表插入元素
/// </summary>
/// <param name="list">双向链表头结点</param>
/// <param name="pos">插入位置</param>
/// <param name="data">数据指针</param>
/// <returns></returns>
Status InsertDuLinkedList(DuLinkedList list, int pos, Data* data);

/// <summary>
/// 双向链表删除元素
/// </summary>
/// <param name="list">双向链表头结点</param>
/// <param name="pos">结点位置</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status RemoveDuLinkedList(DuLinkedList list, int pos, Data* data);

/// <summary>
/// 删除双向链表
/// </summary>
/// <param name="list">双向链表头结点</param>
void DeleteDuLinkedList(DuLinkedList* list);
  • LinkedList.c
#define _CRT_SECURE_NO_WARNINGS
#include "LinkedList.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// ********************** 单链表 **********************

// ---------------- CALLBACK ----------------
void Print_LinkedList(LNode* p)
{
	printf("num = %d  string = %s\n", p->data.num, p->data.string);
}

// ------------ MAIN ------------
LinkedList InitLinkedList()
{
	LinkedList list = (LNode*)malloc(sizeof(LNode));
	if (list)
	{
		list->next = NULL;
		return list;
	}
	else
	{
		exit(-1);
		return NULL;
	}
}

int IsLinkedListEmpty(const LinkedList list)
{
	return !(list->next);
}

int GetLinkedListLength(const LinkedList list)
{
	LNode* p = list->next;
	int count = 0;
	while (p)
	{
		count++;
		p = p->next;
	}
	return count;
}

Status LocateLinkedList(const LinkedList list, int pos, Data* data)
{
	LNode* p = list;
	int count = 0;
	while (p->next && count < pos)
	{
		count++;
		p = p->next;
	}
	if (!p || count > pos)
	{
		return ERROR;
	}
	else
	{
		memcpy(data, &(p->data), sizeof(Data));
		return OK;
	}
}

Status InsertLinkedList(LinkedList list, int pos, Data* data)
{
	LNode* p = list;
	int count = 0;
	while (p && count < pos - 1)
	{
		count++;
		p = p->next;
	}
	if (!p || count > pos - 1)
	{
		return ERROR;
	}
	else
	{
		LNode* node = (LNode*)malloc(sizeof(LNode));
		if (node)
		{
			memcpy(&(node->data), data, sizeof(Data));
			node->next = p->next;
			p->next = node;
			return OK;
		}
		else
		{
			return ERROR;
		}
	}
}

void TraveseLinkedList(LinkedList list, void(*cb)(LNode*))
{
	LNode* p = list->next;
	while (p)
	{
		cb(p);
		p = p->next;
	}
}

Status RemoveLinkedList(LinkedList list, int pos, Data* data)
{
	LNode* p = list;
	int count = 0;
	while (p->next && count < pos - 1)
	{
		count++;
		p = p->next;
	}
	if (!p->next || count > pos - 1)
	{
		return ERROR;
	}
	else
	{
		LNode* tmp = p->next;
		memcpy(data, &tmp->data, sizeof(Data));
		p->next = tmp->next;
		free(tmp);
		return OK;
	}
}

static void ClearLinkedList(LinkedList list)
{
	if (list)
	{
		ClearLinkedList(list->next);
		free(list);
	}
	else
	{
		return;
	}
}

void DeleteLinkedList(LinkedList* list)
{
	ClearLinkedList(*list);
	*list = NULL;
}

void MergeLinkedList(LinkedList list1, LinkedList list2)
{
	LNode* p = list1;
	while (p->next)
	{
		p = p->next;
	}
	p->next = list2->next;
}

// ********************************************

// ********************** 双向链表 **********************

// ------------- CALLBACK -------------
void Print_DuLinkedList(DuLNode* p)
{
	printf("num = %d  string = %s\n", p->data.num, p->data.string);
}

// ------------ MAIN ------------
DuLinkedList InitDuLinkedList()
{
	DuLinkedList list = (DuLNode*)malloc(sizeof(DuLNode));
	if (list)
	{
		list->next = NULL;
		list->prior = NULL;
		return list;
	}
	else
	{
		exit(-1);
		return NULL;
	}
}

void TraveseDuLinkedList(DuLinkedList list, void(*cb)(DuLNode*))
{
	DuLNode* p = list->next;
	while (p)
	{
		cb(p);
		p = p->next;
	}
}

int IsDuLinkedListEmpty(const DuLinkedList list)
{
	return !(list->next);
}

Status InsertDuLinkedList(DuLinkedList list, int pos, Data* data)
{
	DuLNode* p = list;
	int count = 0;
	while (p && count < pos - 1)
	{
		count++;
		p = p->next;
	}
	if (!p || count > pos - 1)
	{
		return ERROR;
	}
	else
	{
		DuLNode* node = (DuLNode*)malloc(sizeof(DuLNode));
		if (node)
		{
			memcpy(&node->data, data, sizeof(Data));
			if (p->next)
			{
				p->next->prior = node;
				node->next = p->next;
				p->next = node;
				node->prior = p;
			}
			else
			{
				node->next = p->next;
				p->next = node;
				node->prior = p;
			}
			return OK;
		}
		else
		{
			return ERROR;
		}
	}
}

Status RemoveDuLinkedList(DuLinkedList list, int pos, Data* data)
{
	DuLNode* p = list;
	int count = 0;
	while (p->next && count < pos - 1)
	{
		count++;
		p = p->next;
	}
	if (!p->next || count > pos - 1)
	{
		return ERROR;
	}
	else
	{
		DuLNode* tmp = p->next;
		if (tmp->next)
		{
			p->next = tmp->next;
			tmp->next->prior = p;
		}
		else
		{
			p->next = tmp->next;
		}
		free(tmp);
		return OK;
	}
}

static void ClearDuLinkedList(DuLinkedList list)
{
	if (list)
	{
		ClearDuLinkedList(list->next);
		free(list);
	}
	else
	{
		return;
	}
}

void DeleteDuLinkedList(DuLinkedList* list)
{
	ClearDuLinkedList(*list);
	*list = NULL;
}
3. 栈
  • Stack.h
#define _CRT_SECURE_NO_WARNINGS
#include "Data.h"

// 定义顺序栈
#define APPEND_SIZE 10
typedef struct SqStack
{
	Data* base;
	Data* top;
	int stacksize;
}SqStack;

// 定义链栈
typedef struct SNode
{
	Data data;
	struct SNode* next;
}SNode, * LinkedStack;

// *************** 顺序栈 ***************

// ---------- CALLBACK ----------
void Print_SqStack(Data* data);

// ---------- MAIN ----------
/// <summary>
/// 初始化顺序栈
/// </summary>
/// <param name="stacksize">栈的分配空间大小</param>
/// <returns>已初始化的栈地址</returns>
SqStack* InitSqStack(int stacksize);

/// <summary>
/// 判断顺序栈是否为空
/// </summary>
/// <param name="stack">顺序栈指针</param>
/// <returns>判断结果</returns>
int IsSqStackEmpty(const SqStack* stack);

/// <summary>
/// 判断顺序栈是否为满
/// </summary>
/// <param name="stack">顺序栈指针</param>
/// <returns>判断结果</returns>
int IsSqStackFull(const SqStack* stack);

/// <summary>
/// 获取顺序栈的长度
/// </summary>
/// <param name="stack">顺序栈指针</param>
/// <returns>顺序栈的长度</returns>
int GetSqStackLength(const SqStack* stack);

/// <summary>
/// 顺序栈压栈
/// </summary>
/// <param name="stack">顺序栈指针</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status PushSqStack(SqStack* stack, Data* data);

/// <summary>
/// 遍历顺序栈
/// </summary>
/// <param name="stack">顺序栈指针</param>
/// <param name="cb">回调函数</param>
void TraverseSqStack(SqStack* stack, void(*cb)(Data*));

/// <summary>
/// 顺序栈弹栈
/// </summary>
/// <param name="stack">顺序栈指针</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status PopSqStack(SqStack* stack, Data* data);

/// <summary>
/// 获取顺序栈的栈顶元素
/// </summary>
/// <param name="stack">顺序栈指针</param>
/// <returns>栈顶元素指针</returns>
Data* GetSqStackTop(SqStack* stack);

// *************** 顺序栈 ***************

// ---------- CALLBACK ----------
void Print_LinkedStack(SNode* p);

// ---------- MAIN ----------
/// <summary>
/// 初始化链栈
/// </summary>
/// <returns>已初始化链栈的地址</returns>
LinkedStack InitLinkedStack();

/// <summary>
/// 判断链栈是否为空
/// </summary>
/// <param name="stack">链栈栈顶指针</param>
/// <returns>判断结果</returns>
int IsLinkedStackEmpty(const LinkedStack stack);

/// <summary>
/// 获取链栈的长度
/// </summary>
/// <param name="stack">链栈栈顶指针</param>
/// <returns>链栈的长度</returns>
int GetLinkedStackLength(const LinkedStack stack);

/// <summary>
/// 链栈压栈
/// </summary>
/// <param name="stack">链栈栈顶元素的二级指针</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status PushLinkedStack(LinkedStack* stack, Data* data);

/// <summary>
/// 遍历链栈
/// </summary>
/// <param name="stack">链栈栈顶指针</param>
/// <param name="cb">回调函数</param>
void TraverseLinkedStack(LinkedStack stack, void(*cb)(SNode*));

/// <summary>
/// 链栈弹栈
/// </summary>
/// <param name="stack">链栈栈顶的二级指针</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status PopLinkedStack(LinkedStack *stack, Data* data);

/// <summary>
/// 获得链栈栈顶元素
/// </summary>
/// <param name="stack">链栈栈顶指针</param>
/// <returns>栈顶元素指针</returns>
Data* GetLinkedStackTop(const LinkedStack stack);
  • Stack.c
#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// *************** 顺序栈 ***************

void Print_SqStack(Data* data)
{
	printf("num = %d  string = %s\n", data->num, data->string);
}

SqStack* InitSqStack(int stacksize)
{
	SqStack* stack = (SqStack*)malloc(sizeof(SqStack));
	if (stack)
	{
		stack->base = (Data*)malloc(sizeof(Data) * stacksize);
		if (stack->base)
		{
			stack->top = stack->base;
			stack->stacksize = stacksize;
			return stack;
		}
		else
		{
			exit(-1);
			free(stack);
			return NULL;
		}
	}
	else
	{
		exit(-1);
		return NULL;
	}
}

int IsSqStackEmpty(const SqStack* stack)
{
	return stack->base == stack->top;
}

int IsSqStackFull(const SqStack* stack)
{
	return stack->top - stack->base == stack->stacksize;
}

int GetSqStackLength(const SqStack* stack)
{
	return stack->top - stack->base;
}

static Status ExpandSqStack(SqStack* stack, int size)
{
	int len = GetSqStackLength(stack);
	Data* tmp = (Data*)realloc(stack->base, sizeof(Data) * (stack->stacksize + size));
	if (tmp)
	{
		stack->base = tmp;
		stack->top = stack->base + len;
		stack->stacksize += size;
		return OK;
	}
	else
	{
		exit(-1);
		return ERROR;
	}
}

void TraverseSqStack(SqStack* stack, void(*cb)(Data*))
{
	int len = GetSqStackLength(stack);
	for (int i = len - 1; i >= 0; i--)
	{
		cb(stack->base + i);
	}
}

Status PushSqStack(SqStack* stack, Data* data)
{
	if (IsSqStackFull(stack))	ExpandSqStack(stack, APPEND_SIZE);
	memcpy(stack->top++, data, sizeof(Data));
	return OK;
}

Status PopSqStack(SqStack* stack, Data* data)
{
	if (IsSqStackEmpty(stack))	return ERROR;
	memcpy(data, --stack->top, sizeof(Data));
	return OK;
}

Data* GetSqStackTop(SqStack* stack)
{
	return stack->top != stack->base ? stack->top - 1 : NULL;
}

// *************** 链栈 ***************

void Print_LinkedStack(SNode* p)
{
	printf("num = %d  string = %s\n", p->data.num, p->data.string);
}

LinkedStack InitLinkedStack()
{
	return NULL;
}

int IsLinkedStackEmpty(const LinkedStack stack)
{
	return !stack;
}

int GetLinkedStackLength(const LinkedStack stack)
{
	int count = 0;
	SNode* p = stack;
	while (p)
	{
		count++;
		p = p->next;
	}
	return count;
}

Status PushLinkedStack(LinkedStack* stack, Data* data)
{
	SNode* p = (SNode*)malloc(sizeof(SNode));
	if (p)
	{
		memcpy(&p->data, data, sizeof(Data));
		p->next = *stack;
		*stack = p;
		return OK;
	}
	else
	{
		exit(-1);
		return ERROR;
	}
}

void TraverseLinkedStack(LinkedStack stack, void(*cb)(SNode*))
{
	SNode* p = stack;
	while (p)
	{
		cb(p);
		p = p->next;
	}
}

Status PopLinkedStack(LinkedStack* stack, Data* data)
{
	if (IsLinkedStackEmpty(*stack))	return ERROR;
	SNode* p = *stack;
	memcpy(data, &(*stack)->data, sizeof(Data));
	*stack = (*stack)->next;
	free(p);
	return OK;
}

Data* GetLinkedStackTop(const LinkedStack stack)
{
	return IsLinkedStackEmpty(stack) ? NULL : &stack->data;
}
4. 队列
  • Queue.h
#pragma once
#include "Data.h"

// 定义循环队列
#define MAXQSIZE 5
typedef struct SqQueue
{
	Data* base;
	int front;
	int rear;
}SqQueue;

// 定义链队
typedef struct QNode
{
	Data data;
	struct QNode* next;
}QNode;

typedef struct LinkedQueue
{
	QNode* front;
	QNode* rear;
}LinkedQueue;

// *************** 循环队列 ***************

// ----------- CALLBACK -----------
void Print_SqQueue(Data* data);

// ----------- MAIN -----------
/// <summary>
/// 初始化循环队列
/// </summary>
/// <returns>已初始化的循环队列的地址</returns>
SqQueue* InitSqQueue();

/// <summary>
/// 判断循环队列是否为空
/// </summary>
/// <param name="queue">循环队列指针</param>
/// <returns>判断结果</returns>
int IsSqQueueEmpty(const SqQueue* queue);

/// <summary>
/// 判断循环队列是否为满
/// </summary>
/// <param name="queue">循环队列指针</param>
/// <returns>判断结果</returns>
int IsSqQueueFull(const SqQueue* queue);

/// <summary>
/// 获取循环队列长度
/// </summary>
/// <param name="queue">循环队列指针</param>
/// <returns>循环队列长度</returns>
int GetSqQueueLength(const SqQueue* queue);

/// <summary>
/// 循环队列入队
/// </summary>
/// <param name="queue">循环队列指针</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status EnSqQueue(SqQueue* queue, Data* data);

/// <summary>
/// 遍历循环队列
/// </summary>
/// <param name="queue">循环队列指针</param>
/// <param name="cb">回调函数</param>
void TraverseSqQueue(SqQueue* queue, void(*cb)(Data*));

/// <summary>
/// 循环队列出队
/// </summary>
/// <param name="queue">循环队列指针</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status DeSqQueue(SqQueue* queue, Data* data);

/// <summary>
/// 获取循环队列队头元素
/// </summary>
/// <param name="queue">循环队列指针</param>
/// <returns>队头元素</returns>
Data* GetSqQueueHead(const SqQueue* queue);

// *************** 链队 ***************

// -------------- CALLBACK --------------
void Print_LinkedQueue(QNode* p);

// -------------- MAIN --------------
/// <summary>
/// 初始化链队
/// </summary>
/// <returns>已初始化的链队地址</returns>
LinkedQueue* InitLinkedQueue();

/// <summary>
/// 判断链队是否为空
/// </summary>
/// <param name="queue">链队指针</param>
/// <returns>判断结果</returns>
int IsLinkedQueueEmpty(const LinkedQueue* queue);

/// <summary>
/// 链队入队
/// </summary>
/// <param name="queue">链队指针</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status EnLinkedQueue(LinkedQueue* queue, Data* data);

/// <summary>
/// 遍历链队
/// </summary>
/// <param name="queue">链队指针</param>
/// <param name="cb">回调函数</param>
void TraverseLinkedQueue(LinkedQueue* queue, void(*cb)(QNode*));

/// <summary>
/// 获取链队长度
/// </summary>
/// <param name="queue">链队指针</param>
/// <returns>链队长度</returns>
int GetLinkedQueueLength(const LinkedQueue* queue);

/// <summary>
/// 链队出队
/// </summary>
/// <param name="queue">链队指针</param>
/// <param name="data">数据指针</param>
/// <returns>状态码</returns>
Status DeLinkedQueue(LinkedQueue* queue, Data* data);

/// <summary>
/// 获取链队队头元素
/// </summary>
/// <param name="queue">链队指针</param>
/// <returns>队头元素</returns>
Data* GetLinkedQueueHead(const LinkedQueue* queue);
  • Queue.c
#define _CRT_SECURE_NO_WARNINGS
#include "Queue.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// *************** 循环队列 ***************

void Print_SqQueue(Data* data)
{
	printf("num = %d  string = %s\n", data->num, data->string);
}

SqQueue* InitSqQueue()
{
	SqQueue* queue = (SqQueue*)malloc(sizeof(SqQueue));
	if (queue)
	{
		queue->base = (Data*)malloc(sizeof(Data) * MAXQSIZE);
		if (queue->base)
		{
			queue->front = 0;
			queue->rear = 0;
			return queue;
		}
		else
		{
			free(queue);
			exit(-1);
			return NULL;
		}
	}
	else
	{
		exit(-1);
		return NULL;
	}
}

int IsSqQueueEmpty(const SqQueue* queue)
{
	return queue->front == queue->rear;
}

int IsSqQueueFull(const SqQueue* queue)
{
	return (queue->rear + 1) % MAXQSIZE == queue->front;
}

int GetSqQueueLength(const SqQueue* queue)
{
	return (queue->rear - queue->front + MAXQSIZE) % MAXQSIZE;
}

Status EnSqQueue(SqQueue* queue, Data* data)
{
	if (IsSqQueueFull(queue))	
		return ERROR;
	memcpy(queue->base + queue->rear, data, sizeof(Data));
	queue->rear = (queue->rear + 1) % MAXQSIZE;
	return OK;
}

void TraverseSqQueue(SqQueue* queue, void(*cb)(Data*))
{
	int i = queue->front;
	while (i != queue->rear)
	{
		cb(queue->base + i);
		i = (i + 1) % MAXQSIZE;
	}
}

Status DeSqQueue(SqQueue* queue, Data* data)
{
	if (IsSqQueueEmpty(queue))
		return ERROR;
	memcpy(data, queue->base + queue->front, sizeof(Data));
	queue->front = (queue->front + 1) % MAXQSIZE;
	return OK;
}

Data* GetSqQueueHead(const SqQueue* queue)
{
	return IsSqQueueEmpty(queue) ? NULL : queue->base + queue->front;
}

// *************** 链队 ***************

void Print_LinkedQueue(QNode* p)
{
	printf("num = %d  string = %s\n", p->data.num, p->data.string);
}

LinkedQueue* InitLinkedQueue()
{
	LinkedQueue* queue = (LinkedQueue*)malloc(sizeof(LinkedQueue));
	if (queue)
	{
		queue->front = (QNode*)malloc(sizeof(QNode));
		if (queue->front)
		{
			queue->front->next = NULL;
			queue->rear = queue->front;
			return queue;
		}
		else
		{
			free(queue);
			exit(-1);
			return NULL;
		}
	}
	else
	{
		exit(-1);
		return NULL;
	}
}

int IsLinkedQueueEmpty(const LinkedQueue* queue)
{
	return queue->front == queue->rear;
}

Status EnLinkedQueue(LinkedQueue* queue, Data* data)
{
	QNode* p = (QNode*)malloc(sizeof(QNode));
	if (p)
	{
		memcpy(&p->data, data, sizeof(Data));
		p->next = NULL;
		queue->rear->next = p;
		queue->rear = p;
		return OK;
	}
	else
	{
		exit(-1);
		return ERROR;
	}
}

void TraverseLinkedQueue(LinkedQueue* queue, void(*cb)(QNode*))
{
	QNode* p = queue->front->next;
	while (p)
	{
		cb(p);
		p = p->next;
	}
}

int GetLinkedQueueLength(const LinkedQueue* queue)
{
	QNode* p = queue->front->next;
	int count = 0;
	while (p)
	{
		count++;
		p = p->next;
	}
	return count;
}

Status DeLinkedQueue(LinkedQueue* queue, Data* data)
{
	if (IsLinkedQueueEmpty(queue))
		return ERROR;
	QNode* tmp = queue->front->next;
	memcpy(data, &tmp->data, sizeof(Data));
	queue->front->next = tmp->next;
	free(tmp);
	if (!queue->front->next)
	{
		queue->rear = queue->front;
	}
	return OK;
}

Data* GetLinkedQueueHead(const LinkedQueue* queue)
{
	return IsLinkedQueueEmpty(queue) ? NULL : &queue->front->next->data;
}

5. 二叉树
  • BiTree.h
#pragma once
#include "Data.h"

// 定义二叉树
typedef struct TNode
{
	Data data;
	struct TNode* lchild;
	struct TNode* rchild;
}TNode, * BiTree;

// 定义哈夫曼树
typedef struct HTNode
{
	int weight;
	int parent, lchild, rchild;
}HTNode, * HuffmanTree;

// 定义哈夫曼编码
typedef char** HuffmanCode;

// ******************** 二叉树 ********************

// ------------ CALLBACK ------------
void Print_BiTree(TNode* p);

// ------------ MAIN ------------

/// <summary>
/// 先序创建二叉树
/// </summary>
/// <param name="t">二叉树的指针</param>
/// <param name="dataArr">数据数组</param>
void CreateBiTree_DLR(BiTree* t, Data* dataArr);

/// <summary>
/// 先序遍历二叉树
/// </summary>
/// <param name="t">二叉树根结点</param>
/// <param name="cb">回调函数</param>
void Traverse_DLR(const BiTree t, void(*cb)(TNode*));

/// <summary>
/// 中序遍历二叉树
/// </summary>
/// <param name="t">二叉树根结点</param>
/// <param name="cb">回调函数</param>
void Traverse_LDR(const BiTree t, void(*cb)(TNode*));

/// <summary>
/// 后序遍历二叉树
/// </summary>
/// <param name="t">二叉树根结点</param>
/// <param name="cb">回调函数</param>
void Traverse_LRD(const BiTree t, void(*cb)(TNode*));

/// <summary>
/// 拷贝二叉树
/// </summary>
/// <param name="des">目标二叉树的指针</param>
/// <param name="src">源二叉树</param>
void CopyBiTree(BiTree* des, const BiTree src);

/// <summary>
/// 获取二叉树的深度
/// </summary>
/// <param name="t">二叉树根结点</param>
/// <returns>二叉树深度</returns>
int GetBiTreeDepth(const BiTree t);

/// <summary>
/// 获取二叉树结点个数
/// </summary>
/// <param name="t">二叉树根结点</param>
/// <returns>二叉树结点个数</returns>
int GetBiTreeNodeCount(const BiTree t);

// ******************** 哈夫曼树 ********************

// ------------ MAIN ------------
/// <summary>
/// 创建哈夫曼树
/// </summary>
/// <param name="weightArr">权重数组</param>
/// <param name="arrLen">权重数组长度</param>
/// <returns>哈夫曼树</returns>
HuffmanTree CreateHuffmanTree(int* weightArr, int arrLen);

/// <summary>
/// 打印哈夫曼树
/// </summary>
/// <param name="ht">哈夫曼树</param>
void PrintHuffmanTree(const HuffmanTree ht);

/// <summary>
/// 创建哈夫曼编码
/// </summary>
/// <param name="weightArr">权重数组</param>
/// <param name="arrLen">数组长度</param>
/// <returns>哈夫曼编码</returns>
HuffmanCode CreateHuffmanCode(int* weightArr, int arrLen);

/// <summary>
/// 打印哈夫曼编码
/// </summary>
/// <param name="hc">哈夫曼编码</param>
/// <param name="len">字符个数</param>
void PrintHuffmanCode(const HuffmanCode hc, int len);
  • BiTree.c
#define _CRT_SECURE_NO_WARNINGS
#include "BiTree.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// ******************** 二叉树 ********************

void Print_BiTree(TNode* p)
{
	printf("num = %d  string = %s\n", p->data.num, p->data.string);
}

static int IsDataEmpty(Data* data)
{
	Data tmp = { 0 };
	return memcmp(data, &tmp, sizeof(Data)) == 0;
}

void CreateBiTree_DLR(BiTree* t, Data* dataArr)
{
	static int i = 0;
	// 未到达空数据域,生成新结点
	if (!IsDataEmpty(dataArr + i))
	{
		*t = (TNode*)malloc(sizeof(TNode));
		if (*t)
		{
			memcpy(&(*t)->data, dataArr + i++, sizeof(Data));
			CreateBiTree_DLR(&((*t)->lchild), dataArr);
			CreateBiTree_DLR(&((*t)->rchild), dataArr);
		}
		else
		{
			exit(-1);
			return;
		}
	}
	// 到达空数据域,弹栈
	else
	{
		i++;
		*t = NULL;
		return;
	}
}

void Traverse_DLR(const BiTree t, void(*cb)(TNode*))
{
	if (t)
	{
		cb(t);
		Traverse_DLR(t->lchild, cb);
		Traverse_DLR(t->rchild, cb);
	}
	else
	{
		return;
	}
}

void Traverse_LDR(const BiTree t, void(*cb)(TNode*))
{
	if (t)
	{
		Traverse_LDR(t->lchild, cb);
		cb(t);
		Traverse_LDR(t->rchild, cb);
	}
	else
	{
		return;
	}
}

void Traverse_LRD(const BiTree t, void(*cb)(TNode*))
{
	if (t)
	{
		Traverse_LRD(t->lchild, cb);
		Traverse_LRD(t->rchild, cb);
		cb(t);
	}
	else
	{
		return;
	}
}

void CopyBiTree(BiTree* des, const BiTree src)
{
	if (src)
	{
		*des = (TNode*)malloc(sizeof(TNode));
		if (*des)
		{
			memcpy(&(*des)->data, &src->data, sizeof(Data));
			CopyBiTree(&(*des)->lchild, src->lchild);
			CopyBiTree(&(*des)->rchild, src->rchild);
		}
		else
		{
			exit(-1);
			return;
		}
	}
	else
	{
		*des = NULL;
		return;
	}
}

int GetBiTreeDepth(const BiTree t)
{
	if (t)
	{
		int ld = GetBiTreeDepth(t->lchild);
		int rd = GetBiTreeDepth(t->rchild);
		return ld > rd ? ld + 1 : rd + 1;
	}
	else
	{
		return 0;
	}
}

int GetBiTreeNodeCount(const BiTree t)
{
	if (t)
	{
		return GetBiTreeNodeCount(t->lchild) + GetBiTreeNodeCount(t->rchild) + 1;
	}
	else
	{
		return 0;
	}
}

// ******************** 哈夫曼树 ********************

static void Select(const HuffmanTree ht, int maxPos, int* i1, int* i2)
{
	*i1 = 9999;
	*i2 = 9999;
	for (int i = 1; i <= maxPos; i++)
	{
		if (!ht[i].parent && *i1 > ht[i].weight)
		{
			*i1 = i;
		}
	}
	for (int i = 1; i <= maxPos; i++)
	{
		if (i != *i1 && !ht[i].parent && *i2 > ht[i].weight)
		{
			*i2 = i;
		}
	}
}

/// <summary>
/// 创建哈夫曼树
/// </summary>
/// <param name="weightArr">权重数组</param>
/// <param name="arrLen">权重数组长度</param>
/// <returns>哈夫曼树</returns>
HuffmanTree CreateHuffmanTree(int* weightArr, int arrLen)
{
	if (arrLen <= 1) return NULL;
	int treeLen = arrLen * 2 - 1;
	HuffmanTree ht = (HuffmanTree)malloc(sizeof(HTNode) * (treeLen + 1));
	if (ht)
	{
		// 初始化哈夫曼树
		for (int i = 1; i <= treeLen; i++)
		{
			ht[i].parent = 0;
			ht[i].lchild = 0;
			ht[i].rchild = 0;
		}
		for (int i = 1; i <= arrLen; i++)
		{
			ht[i].weight = weightArr[i - 1];
		}

		// 构造哈夫曼树
		int s1 = 0;
		int s2 = 0;
		for (int i = arrLen + 1; i <= treeLen; i++)
		{
			Select(ht, i - 1, &s1, &s2);
			ht[i].lchild = s1;
			ht[i].rchild = s2;
			ht[i].weight = ht[s1].weight + ht[s2].weight;
			ht[s1].parent = i;
			ht[s2].parent = i;
		}
		return ht;
	}
	else
	{
		exit(-1);
		return NULL;
	}
}

void PrintHuffmanTree(const HuffmanTree ht)
{
	int i = 1;
	while (ht[i].parent)
	{
		printf("%d\t%d\t%d\t%d\t%d\n", i, ht[i].weight, ht[i].parent, ht[i].lchild, ht[i].rchild);
		i++;
	}
	printf("%d\t%d\t%d\t%d\t%d\n", i, ht[i].weight, ht[i].parent, ht[i].lchild, ht[i].rchild);
}

HuffmanCode CreateHuffmanCode(int* weightArr, int arrLen)
{
	if (arrLen <= 1) return NULL;
	// 创建哈夫曼树
	HuffmanTree ht = CreateHuffmanTree(weightArr, arrLen);
	if (!ht)	
		return NULL;

	// 初始化哈夫曼编码
	HuffmanCode hc = (HuffmanCode)malloc(sizeof(char*) * (arrLen + 1));
	if (!hc)
	{
		exit(-1);
		return NULL;
	}
	else
	{
		char* cd = (char*)malloc(sizeof(char) * arrLen);
		if (!cd)
		{
			exit(-1);
			return NULL;
		}
		else
		{
			int start = 0;
			int c = 0;
			int f = 0;
			cd[arrLen - 1] = 0;
			// 逐个字符求哈夫曼编码
			for (int i = 1; i <= arrLen; i++)
			{
				start = arrLen - 1;
				c = i;
				f = ht[i].parent;
				while (f != 0)
				{
					start--;
					if (ht[f].lchild == c)
					{
						cd[start] = '0';
					}
					else
					{
						cd[start] = '1';
					}
					c = f;
					f = ht[f].parent;
				}
				// 为第i个字符编码分配空间
				hc[i] = (char*)malloc(sizeof(char) * (arrLen - start));
				strcpy(hc[i], &cd[start]);
			}
			free(cd);
		}
	}
	return hc;
}

void PrintHuffmanCode(const HuffmanCode hc, int len)
{
	for (int i = 1; i <= len; i++)
	{
		printf("%s\n", hc[i]);
	}
}