数据结构笔记
动态数组实现
数据的初始化、指定位置插入、头部删除、尾部删除、指定位置删除。
头文件:
#pragma once
#include<stdlib.h>
#include<string.h>
struct DynamicArray{
void **data; //数据空间首地址
int capacity;//容量,当前数据空间最大能够容纳多少个元素
int size; //大小,当前数据空间有多少元素
};
#ifdef __cplusplus
extern "C"{
#endif
typedef int(compare)(void*, void*);
//初始化函数
void *Init_DynamicArray();
//指定位置插入
int Insert_DynamicArray(void *arr, int pos, void *data);
//头部插入
int PushFront_DynamicArray(void *arr, void *data);
//尾部插入
int PushBack_DynamicArray(void *arr, void *data);
//指定位置删除
int RemoveByPos_DynamicArray(void *arr, int pos);
//根据值来删除
int RemoveByVal_DynamicArray(void *arr, void *data, compare *mycompare);
//头部删除
int PopFront_DynamicArray(void *arr);
//尾部删除
int PopBack_DynamicArray(void *arr);
//获得数组大小
int Size_DynamicArray(void *arr);
//获得容量
int Capacity_DynamicArray(void *arr);
//打印函数
void Foreach_DynamicArray(void *arr,void(*foreach)(void *));
//销毁数组
int Destroy_DynamicArray(void *arr);
#ifdef __cplusplus
}
#endif
头文件实现:
#include"DynamicArray.h"
//初始化函数
void *Init_DynamicArray(){
struct DynamicArray *arr = malloc(sizeof(struct DynamicArray));
if (NULL == arr){
return NULL;
}
arr->capacity = 10; //默认数组创建,容量是10
arr->data = malloc(sizeof(void *)* arr->capacity);
arr->size = 0;
return arr;
}
//指定位置插入
int Insert_DynamicArray(void *arr, int pos, void *data){
if (NULL == arr){
return -1;
}
if (NULL == data){
return -2;
}
struct DynamicArray *myarr = (struct DynamicArray *)arr;
if (pos < 0 || pos > myarr->size){
pos = myarr->size;
}
//判断空间是否足够
if (myarr->size == myarr->capacity){
//根据增长策略,计算新空间大小
int newcapacity = myarr->size * 2;
//开辟新空间
void **newspace = (void **)malloc(sizeof(void *)* newcapacity);
//将旧空间的数据拷贝到新空间
memcpy(newspace, myarr->data, sizeof(void *)* myarr->capacity);
//释放旧空间内存
free(myarr->data);
//更新数组核心数据
myarr->data = newspace;
myarr->capacity = newcapacity;
}
//将元素插入到新空间
for (int i = myarr->size - 1; i >= pos;i --){
myarr->data[i + 1] = myarr->data[i];
}
//元素插入到pos位置
myarr->data[pos] = data;
//维护size大小
myarr->size++;
return 0;
}
//头部插入
int PushFront_DynamicArray(void *arr, void *data){
return Insert_DynamicArray(arr, 0 , data);
}
//尾部插入
int PushBack_DynamicArray(void *arr, void *data){
struct DynamicArray *myarr = (struct DynamicArray *)arr;
return Insert_DynamicArray(arr, myarr->size, data);
}
//指定位置删除
int RemoveByPos_DynamicArray(void *arr, int pos){
if (NULL == arr){
return -1;
}
struct DynamicArray *myarr = (struct DynamicArray *)arr;
if (myarr->size == 0){
return 0;
}
if (pos < 0 || pos > myarr->size - 1){
return 0;
}
for (int i = pos; i < myarr->size - 1; i ++){
myarr->data[i] = myarr->data[i + 1];
}
myarr->size--;
return 0;
}
//根据值来删除
int RemoveByVal_DynamicArray(void *arr, void *data, compare *mycompare){
if (NULL == arr){
return -1;
}
if (NULL == data){
return -2;
}
if (NULL == mycompare){
return -3;
}
struct DynamicArray *myarr = (struct DynamicArray *)arr;
if (myarr->size == 0){
return 0;
}
for (int i = 0; i < myarr->size - 1;i ++){
if (mycompare(myarr->data[i], data)){
//说明找到了
RemoveByPos_DynamicArray(arr, i);
break;
}
}
return 0;
}
//头部删除
int PopFront_DynamicArray(void *arr){
return RemoveByPos_DynamicArray(arr, 0);
}
//尾部删除
int PopBack_DynamicArray(void *arr){
struct DynamicArray *myarr = (struct DynamicArray *)arr;
return RemoveByPos_DynamicArray(arr, myarr->size - 1);
}
//获得数组大小
int Size_DynamicArray(void *arr){
struct DynamicArray *myarr = (struct DynamicArray *)arr;
return myarr->size;
}
//获得容量
int Capacity_DynamicArray(void *arr){
struct DynamicArray *myarr = (struct DynamicArray *)arr;
return myarr->capacity;
}
//打印函数
void Foreach_DynamicArray(void *arr, void(*foreach)(void *)){
if (NULL == arr){
return;
}
if (NULL == foreach){
return;
}
struct DynamicArray *myarr = (struct DynamicArray *)arr;
for (int i = 0; i < myarr->size; i++){
foreach(myarr->data[i]);
}
}
//销毁数组
int Destroy_DynamicArray(void *arr){
if (NULL == arr){
return -1;
}
struct DynamicArray *myarr = (struct DynamicArray *)arr;
if (myarr->data != NULL){
myarr->capacity = 0;
myarr->size = 0;
free(myarr->data);
myarr->data = NULL;
}
free(myarr);
myarr = NULL;
return 0;
}
测试文件:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"DynamicArray.h"
struct Person{
char name[64];
int age;
};
void myPrint(void *data){
struct Person *person = (struct Person *)data;
printf("Name:%s Age:%d\n",person->name,person->age);
}
int myComapre(void *d1, void *d2){
struct Person *p1 = (struct Person *)d1;
struct Person *p2 = (struct Person *)d2;
return (strcmp(p1->name, p2->name) == 0) && p1->age == p2->age;
}
void test(){
struct Person p1 = { "aaa", 10 };
struct Person p2 = { "bbb", 20 };
struct Person p3 = { "ccc", 30 };
struct Person p4 = { "ddd", 40 };
struct Person p5 = { "eee", 50 };
struct Person p6 = { "fff", 60 };
struct Person p7 = { "ggg", 70 };
struct Person p8 = { "hhh", 80 };
struct Person p9 = { "iii", 90 };
struct Person p10 = { "jjj", 100 };
struct Person p11 = { "kkk", 110 };
//初始化数组
void *myarray = Init_DynamicArray();
//插入元素
Insert_DynamicArray(myarray, 0, &p1);
Insert_DynamicArray(myarray, 0, &p2);
Insert_DynamicArray(myarray, 0, &p3);
Insert_DynamicArray(myarray, 0, &p4);
Insert_DynamicArray(myarray, 0, &p5);
Insert_DynamicArray(myarray, 100, &p6);
printf("Capacity:%d\n", Capacity_DynamicArray(myarray));
PushFront_DynamicArray(myarray, &p7);
PushFront_DynamicArray(myarray, &p8);
PushFront_DynamicArray(myarray, &p9);
PushBack_DynamicArray(myarray, &p10);
PushBack_DynamicArray(myarray, &p11);
//遍历 //9 8 7 5 4 3 2 1 6 10 11
Foreach_DynamicArray(myarray, myPrint);
printf("Capacity:%d\n",Capacity_DynamicArray(myarray));
printf("Size:%d\n", Size_DynamicArray(myarray));
printf("--------头删和尾删之后-------------\n");
//删除
PopFront_DynamicArray(myarray);
PopBack_DynamicArray(myarray);
Foreach_DynamicArray(myarray, myPrint);
printf("--------删除2位置之后-------------\n");
RemoveByPos_DynamicArray(myarray, 2);
Foreach_DynamicArray(myarray, myPrint);
printf("--------删除age = 10 name = aaa位置之后-------------\n");
struct Person pDel = { "aaa", 10 };
RemoveByVal_DynamicArray(myarray, &pDel, myComapre);
Foreach_DynamicArray(myarray, myPrint);
//销毁
Destroy_DynamicArray(myarray);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
队列
一种先进先出的数据结构,一端插入一端删除。
存储方式:分为顺序队列、链式队列
队列顺序存储:
头文件:
#pragma once
#include<stdlib.h>
//顺序队列
struct SQueue{
void *data[1024]; //保存数据的内存
int size;
};
typedef void *SeqQueue;
#ifdef __cplusplus
extern "C"{
#endif
//初始化
SeqQueue Init_SeqQueue();
//入队
void Push_SeqQueue(SeqQueue queue, void *data);
//出队
void Pop_SeqQueue(SeqQueue queue);
//获得队头元素
void *Front_SeqQueue(SeqQueue queue);
//获得队尾元素
void *Back_SeqQueue(SeqQueue queue);
//获得队列大小
int Size_SeqQueue(SeqQueue queue);
//销毁队列
void Destroy_SeqQueue(SeqQueue queue);
#ifdef __cplusplus
}
#endif
头文件实现:
#include"SeqQueue.h"
//初始化
SeqQueue Init_SeqQueue(){
struct SQueue *queue = malloc(sizeof(struct SQueue));
if (NULL == queue){
return NULL;
}
queue->size = 0;
for (int i = 0; i < 1024; i ++){
queue->data[i] = NULL;
}
return queue;
}
//入队
void Push_SeqQueue(SeqQueue queue, void *data){
if (NULL == queue){
return;
}
if (NULL == data){
return;
}
struct SQueue *q = (struct SQueue *)queue;
if (q->size == 1024){
return;
}
//移动元素,把0号位置空出来
for (int i = q->size - 1; i >= 0; i--){
q->data[i + 1] = q->data[i];
}
q->data[0] = data;
q->size++;
}
//出队
void Pop_SeqQueue(SeqQueue queue){
if (NULL == queue){
return;
}
struct SQueue *q = (struct SQueue *)queue;
if (q->size == 0){
return;
}
q->size--;
}
//获得队头元素
void *Front_SeqQueue(SeqQueue queue){
if (NULL == queue){
return NULL;
}
struct SQueue *q = (struct SQueue *)queue;
return q->data[q->size - 1];
}
//获得队尾元素
void *Back_SeqQueue(SeqQueue queue){
if (NULL == queue){
return NULL;
}
struct SQueue *q = (struct SQueue *)queue;
return q->data[0];
}
//获得队列大小
int Size_SeqQueue(SeqQueue queue){
if (NULL == queue){
return -1;
}
struct SQueue *q = (struct SQueue *)queue;
return q->size;
}
//销毁队列
void Destroy_SeqQueue(SeqQueue queue){
if (NULL == queue){
return;
}
free(queue);
queue = NULL;
}
测试文件:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"SeqQueue.h"
struct Person{
char name[64];
int age;
};
void test(){
//创建数据
struct Person p1 = { "aaa", 10 };
struct Person p2 = { "bbb", 20 };
struct Person p3 = { "ccc", 30 };
struct Person p4 = { "ddd", 40 };
struct Person p5 = { "eee", 50 };
//初始化队列
SeqQueue queue = Init_SeqQueue();
//数据入队列
Push_SeqQueue(queue, &p1);
Push_SeqQueue(queue, &p2);
Push_SeqQueue(queue, &p3);
Push_SeqQueue(queue, &p4);
Push_SeqQueue(queue, &p5);
//输出队头 队尾元素
struct Person *front = (struct Person *)Front_SeqQueue(queue);
struct Person *back = (struct Person *)Back_SeqQueue(queue);
printf("队头元素: Name:%s Age:%d\n",front->name,front->age);
printf("队尾元素: Name:%s Age:%d\n", back->name, back->age);
printf("-----------------------------\n");
//输出队列中元素
while (Size_SeqQueue(queue) > 0){
//获得对头元素
front = (struct Person *)Front_SeqQueue(queue);
printf("Name:%s Age:%d\n", front->name, front->age);
//弹出队头元素
Pop_SeqQueue(queue);
}
//打印大小
printf("Size:%d\n",Size_SeqQueue(queue));
//销毁队列
Destroy_SeqQueue(queue);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
队列的链式存储:
头文件:
#pragma once #include"LinkList.h" struct QueueNode{ struct LinkNode node; }; #ifdef __cplusplus extern "C"{ #endif //初始化链式队列 void *Init_LinkQueue(); //入队列 void Push_LinkQueue(void *queue, void *data); //出队 void Pop_LinkQueue(void *queue); //大小 int Size_LinkQueue(void *queue); //获得队头元素 void *Front_LinkQueue(void *queue); //获得队尾元素 void *Back_LinkQueue(void *queue); //销毁队列 void Destroy_LinkQueue(void *queue); #ifdef __cplusplus } #endif
#pragma once
#include<stdlib.h>
//链表小节点
//目的 : 第一,让用户数据包含 第二,我需要把用户指针类型转换成struct LinkNode*类型
struct LinkNode{
struct LinkNode *next;
};
//链表结构体
struct LList{
struct LinkNode header;
int size;
};
typedef void *LinkList;
//初始化
LinkList Init_LinkList();
//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data);
//位置删除
void RemoveByPos_LinkList(LinkList list, int pos);
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *));
//根据位置获得值
void *Get_LinkList(LinkList list,int pos);
int Size_LinkList(LinkList list);
//销毁
void Destroy_LinkList(LinkList list);
头文件实现:
#include"LinkQueue.h"
//初始化链式队列
void *Init_LinkQueue(){
return Init_LinkList();
}
//入队列
void Push_LinkQueue(void *queue, void *data){
Insert_LinkList(queue, 0, data);
}
//出队
void Pop_LinkQueue(void *queue){
RemoveByPos_LinkList(queue, Size_LinkList(queue) - 1);
}
//大小
int Size_LinkQueue(void *queue){
return Size_LinkList(queue);
}
//获得队头元素
void *Front_LinkQueue(void *queue){
return Get_LinkList(queue , Size_LinkList(queue) - 1);
}
//获得队尾元素
void *Back_LinkQueue(void *queue){
return Get_LinkList(queue, 0);
}
//销毁队列
void Destroy_LinkQueue(void *queue){
Destroy_LinkList(queue);
}
#include"LinkList.h"
//初始化
LinkList Init_LinkList(){
struct LList *list = malloc(sizeof(struct LList));
if (NULL == list){
return NULL;
}
list->header.next = NULL;
list->size = 0;
return list;
}
//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data){
if (NULL == list){
return;
}
if (NULL == data){
return;
}
struct LList *llist = (struct LList *)list;
if (pos < 0 || pos >llist->size){
pos = llist->size;
}
//查找pos位置前一个位置的节点
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos;i ++){
pCurrent = pCurrent->next;
}
//将新节点插入到链表
data->next = pCurrent->next;
pCurrent->next = data;
llist->size++;
}
//位置删除
void RemoveByPos_LinkList(LinkList list, int pos){
if (NULL ==list){
return;
}
struct LList *llist = (struct LList *)list;
if (llist->size == 0){
return;
}
if (pos < 0 || pos > llist->size - 1){
return;
}
//找到pos位置的前一个节点
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos; i ++){
pCurrent = pCurrent->next;
}
//缓存下待删除节点
struct LinkNode *pDel = pCurrent->next;
//重新建立待删除的节点前驱后继节点关系
pCurrent->next = pDel->next;
llist->size--;
}
//根据位置获得值
void *Get_LinkList(LinkList list, int pos){
if (NULL == list){
return NULL;
}
struct LList *llist = (struct LList *)list;
if (pos < 0 || pos > llist->size - 1){
return NULL;
}
//辅助指针变量
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos; i++){
pCurrent = pCurrent->next;
}
return pCurrent->next;
}
int Size_LinkList(LinkList list){
if (NULL == list){
return -1;
}
struct LList *llist = (struct LList *)list;
return llist->size;
}
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *)){
if (NULL == list){
return;
}
struct LList *llist = (struct LList *)list;
//辅助指针变量
struct LinkNode *pCurrent = llist->header.next;
while (pCurrent != NULL){
foreach(pCurrent);
pCurrent = pCurrent->next;
}
}
//销毁
void Destroy_LinkList(LinkList list){
if (NULL == list){
return;
}
free(list);
list = NULL;
}
测试代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkQueue.h"
struct Person{
struct QueueNode node;
char name[64];
int age;
};
void test(){
//创建测试数据
struct Person p1 = { NULL ,"aaa", 10 };
struct Person p2 = { NULL ,"bbb", 20 };
struct Person p3 = { NULL ,"ccc", 30 };
struct Person p4 = { NULL ,"ddd", 40 };
struct Person p5 = { NULL ,"eee", 50 };
void *queue = Init_LinkQueue();
//数据入队
Push_LinkQueue(queue, &p1);
Push_LinkQueue(queue, &p2);
Push_LinkQueue(queue, &p3);
Push_LinkQueue(queue, &p4);
Push_LinkQueue(queue, &p5);
struct Person *front = (struct Person *)Front_LinkQueue(queue);
struct Person *back = (struct Person *)Back_LinkQueue(queue);
printf("Front: Name:%s Age:%d\n",front->name,front->age);
printf("Back: Name:%s Age:%d\n", back->name, back->age);
printf("-------------------------------\n");
//输出队列中的元素
while (Size_LinkQueue(queue) > 0){
front = (struct Person *)Front_LinkQueue(queue);
printf("Name:%s Age:%d\n", front->name, front->age);
//弹出队头元素
Pop_LinkQueue(queue);
}
//销毁队列
Destroy_LinkQueue(queue);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
栈
数据先进后出,以高地址为栈顶。存储方式分为链式存储和顺序存储
顺序存储栈的容器:
顺序栈的头文件:
#pragma once
#include<string.h>
#include<stdlib.h>
#define MAX 1024
//顺序栈
struct SeqStack{
void *data[MAX];
int size;
};
#ifdef __cplusplus
extern "C"{
#endif
//初始化栈
void *Init_SeqStack();
//入栈
void Push_SeqStack(void *stack, void *data);
//出栈
void Pop_SeqStack(void *stack);
//获得大小
int Size_SeqStack(void *stack);
//获得栈顶元素
void *Top_SeqStack(void *stack);
//销毁栈
void Destroy_SeqStack(void *stack);
#ifdef __cplusplus
}
#endif
顺序栈头文件的实现:
#include"SeqStack.h"
//初始化栈
void *Init_SeqStack(){
struct SeqStack *stack = malloc(sizeof(struct SeqStack));
stack->size = 0;
for (int i = 0; i < MAX; i ++){
stack->data[i] = 0;
}
return stack;
}
//入栈
void Push_SeqStack(void *stack, void *data){
if (0 == stack){
return;
}
if (0 == data){
return;
}
struct SeqStack *s = (struct SeqStack *)stack;
s->data[s->size] = data;
s->size++;
}
//出栈
void Pop_SeqStack(void *stack){
if (0 == stack){
return;
}
struct SeqStack *s = (struct SeqStack *)stack;
s->size--;
}
//获得大小
int Size_SeqStack(void *stack){
if (0 == stack){
return -1;
}
struct SeqStack *s = (struct SeqStack *)stack;
return s->size;
}
//获得栈顶元素
void *Top_SeqStack(void *stack){
if (0 == stack){
return NULL;
}
struct SeqStack *s = (struct SeqStack *)stack;
return s->data[s->size - 1];
}
//销毁栈
void Destroy_SeqStack(void *stack){
if (0 == stack){
return;
}
free(stack);
}
测试文件:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"SeqStack.h"
struct Person{
char name[64];
int age;
};
void test(){
//测试数据
struct Person p1 = { "aaa", 10 };
struct Person p2 = { "bbb", 20 };
struct Person p3 = { "ccc", 30 };
struct Person p4 = { "ddd", 40 };
struct Person p5 = { "eee", 50 };
//初始化栈
void *stack = Init_SeqStack();
//数据入栈
Push_SeqStack(stack, &p1);
Push_SeqStack(stack, &p2);
Push_SeqStack(stack, &p3);
Push_SeqStack(stack, &p4);
Push_SeqStack(stack, &p5);
//输出栈中所有元素
while (Size_SeqStack(stack) > 0){
//获得栈顶元素
struct Person * person = (struct Person *)Top_SeqStack(stack);
//输出栈顶元素
printf("Name:%s Age:%d\n",person->name,person->age);
//弹出栈顶元素
Pop_SeqStack(stack);
}
//销毁栈
Destroy_SeqStack(stack);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
链式栈的实现:
链式栈的头文件:
#pragma once
#include<stdlib.h>
struct LinkNode{
struct LinkNode *next;
};
//链式栈
struct LStack{
struct LinkNode header;
int size;
};
typedef void* LinkStack;
#ifdef __cplusplus
extern "C"{
#endif
//初始化
LinkStack Init_LinkStack();
//入栈
void Push_LinkStack(LinkStack stack, void *data);
//出栈
void Pop_LinkStack(LinkStack stack);
//获得栈顶元素
void *Top_LinkStack(LinkStack stack);
//大小
int Size_LinkStack(LinkStack stack);
//销毁栈
void Destroy_LinkStack(LinkStack stack);
#ifdef __cplusplus
}
#endif
头文件的实现:
#include"LinkStack.h"
//初始化
LinkStack Init_LinkStack(){
struct LStack *stack = (struct LStack *)malloc(sizeof(struct LStack));
stack->header.next = NULL;
stack->size = 0;
return stack;
}
//入栈
void Push_LinkStack(LinkStack stack, void *data){
if (NULL == stack){
return;
}
if (data == NULL){
return;
}
struct LStack *s = (struct LStack *)stack;
struct LinkNode *d = (struct LinkNode *)data;
d->next = s->header.next;
s->header.next = d;
s->size++;
}
//出栈
void Pop_LinkStack(LinkStack stack){
if (NULL == stack){
return;
}
struct LStack *s = (struct LStack *)stack;
if (s->size == 0){
return;
}
//缓存下待删除节点
struct LinkNode *pDel = s->header.next;
s->header.next = pDel->next;
s->size--;
}
//获得栈顶元素
void *Top_LinkStack(LinkStack stack){
if (NULL == stack){
return NULL;
}
struct LStack *s = (struct LStack *)stack;
return s->header.next;
}
//大小
int Size_LinkStack(LinkStack stack){
if (NULL == stack){
return -1;
}
struct LStack *s = (struct LStack *)stack;
return s->size;
}
//销毁栈
void Destroy_LinkStack(LinkStack stack){
if (NULL == stack){
return;
}
free(stack);
stack = NULL;
}
测试文件:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkStack.h"
struct Person{
struct LinkNode node;
char name[64];
int age;
};
void test(){
//创建数据
struct Person p1 = { NULL, "aaa", 10 };
struct Person p2 = { NULL, "bbb", 20 };
struct Person p3 = { NULL, "ccc", 30 };
struct Person p4 = { NULL, "ddd", 40 };
struct Person p5 = { NULL, "eee", 50 };
//初始化链式栈
LinkStack stack = Init_LinkStack();
//数据入栈
Push_LinkStack(stack, &p1);
Push_LinkStack(stack, &p2);
Push_LinkStack(stack, &p3);
Push_LinkStack(stack, &p4);
Push_LinkStack(stack, &p5);
//输出栈容器中元素
while (Size_LinkStack(stack) > 0){
//获得栈顶元素
struct Person *person = (struct Person *)Top_LinkStack(stack);
//打印
printf("Name:%s Age:%d\n", person->name, person->age);
//弹出栈顶元素
Pop_LinkStack(stack);
printf("Size:%d\n", Size_LinkStack(stack));
}
printf("----------------\n");
printf("Size:%d\n", Size_LinkStack(stack));
//销毁栈
Destroy_LinkStack(stack);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
以链表作为底层容器,实现栈的操作:
容器头文件和头文件的实现:见数据结构链表的实现
栈的头文件:
#pragma once
#include"LinkList.h"
struct StackNode{
struct LinkNode node;
};
typedef void *LinkStack;
//初始化
LinkStack Init_LinkStack();
//入栈
void Push_LinkStack(LinkStack stack, void *data);
//出栈
void Pop_LinkStack(LinkStack stack);
//获得栈顶元素
void *Top_LinkStack(LinkStack stack);
//大小
int Size_LinkStack(LinkStack stack);
//销毁栈
void Destroy_LinkStack(LinkStack stack);
栈的头文件实现:
#include"LinkStack.h"
//初始化
LinkStack Init_LinkStack(){
return Init_LinkList();
}
//入栈
void Push_LinkStack(LinkStack stack, void *data){
Insert_LinkList(stack, 0, data);
}
//出栈
void Pop_LinkStack(LinkStack stack){
RemoveByPos_LinkList(stack, 0);
}
//获得栈顶元素
void *Top_LinkStack(LinkStack stack){
return Get_LinkList(stack, 0);
}
//大小
int Size_LinkStack(LinkStack stack){
return Size_LinkList(stack);
}
//销毁栈
void Destroy_LinkStack(LinkStack stack){
Destroy_LinkList(stack);
}
测试代码:
define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkStack.h"
struct Person{
struct StackNode node;
char name[64];
int age;
};
void test(){
//创建测试数据
struct Person p1 = { NULL, "aaa", 10 };
struct Person p2 = { NULL, "bbb", 20 };
struct Person p3 = { NULL, "ccc", 30 };
struct Person p4 = { NULL, "ddd", 40 };
struct Person p5 = { NULL, "eee", 50 };
//初始化栈
LinkStack stack = Init_LinkStack();
//数据入栈
Push_LinkStack(stack , &p1);
Push_LinkStack(stack, &p2);
Push_LinkStack(stack, &p3);
Push_LinkStack(stack, &p4);
Push_LinkStack(stack, &p5);
//输出栈中元素
while (Size_LinkStack(stack) > 0){
//获得栈顶元素
struct Person *person = (struct Person*)Top_LinkStack(stack);
//输出元素
printf("Name:%s Age:%d\n",person->name,person->age);
//弹出栈顶元素
Pop_LinkStack(stack);
}
printf("Size%d\n",Size_LinkStack(stack));
//销毁栈
Destroy_LinkStack(stack);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
栈的实例应用与括号匹配
引用栈的顺序存储,实现括号匹配问题查找:
头文件:
#pragma once #include<string.h> #include<stdlib.h> #define MAX 1024 //顺序栈 struct SeqStack{ void *data[MAX]; int size; }; #ifdef __cplusplus extern "C"{ #endif //初始化栈 void *Init_SeqStack(); //入栈 void Push_SeqStack(void *stack, void *data); //出栈 void Pop_SeqStack(void *stack); //获得大小 int Size_SeqStack(void *stack); //获得栈顶元素 void *Top_SeqStack(void *stack); //销毁栈 void Destroy_SeqStack(void *stack);
头文件实现:
#include"SeqStack.h" //初始化栈 void *Init_SeqStack(){ struct SeqStack *stack = malloc(sizeof(struct SeqStack)); stack->size = 0; for (int i = 0; i < MAX; i ++){ stack->data[i] = 0; } return stack; } //入栈 void Push_SeqStack(void *stack, void *data){ if (0 == stack){ return; } if (0 == data){ return; } struct SeqStack *s = (struct SeqStack *)stack; if (s->size == MAX){ return; } s->data[s->size] = data; s->size++; } //出栈 void Pop_SeqStack(void *stack){ if (0 == stack){ return; } struct SeqStack *s = (struct SeqStack *)stack; s->size--; } //获得大小 int Size_SeqStack(void *stack){ if (0 == stack){ return -1; } struct SeqStack *s = (struct SeqStack *)stack; return s->size; } //获得栈顶元素 void *Top_SeqStack(void *stack){ if (0 == stack){ return NULL; } struct SeqStack *s = (struct SeqStack *)stack; return s->data[s->size - 1]; } //销毁栈 void Destroy_SeqStack(void *stack){ if (0 == stack){ return; } free(stack); }
测试函数:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include"SeqStack.h" int IsLeft(char ch){ return ch == '('; } int IsRight(char ch){ return ch == ')'; } void printError(const char *str,const char *errMsg, const char * p){ printf("Error:%s\n",errMsg); printf("%s\n",str); int len = p - str; for (int i = 0; i < len; i ++){ printf(" "); } printf("A\n"); } void test(){ const char *str = "5+)5*(6)+9/(3*1)-(1)+3()"; //初始化栈 void *stack = Init_SeqStack(); char *p = (char *)str; while (*p != '\0'){ //如果是左括号,直接入栈 if (IsLeft(*p)){ Push_SeqStack(stack, p); } //如果是右括号,会有两种情况出现: 1栈不为空,匹配成功,把栈中当前字符弹出 //2栈不为空,右括号没有匹配左括号 if (IsRight(*p)){ if (Size_SeqStack(stack) > 0){ Pop_SeqStack(stack); } else{ printError(str, "没有匹配的左括号!", p); } } p++; } //判断栈是否为空 while (Size_SeqStack(stack) > 0){ //获得栈顶元素 char *pChar = (char *)Top_SeqStack(stack); //弹出栈顶元素 Pop_SeqStack(stack); //输出错误信息 printError(str, "没有匹配的右括号!", pChar); } } int main(){ test(); system("pause"); return EXIT_SUCCESS; }
传统链表实现与Linux内核链表
头文件:
#pragma once
#include<stdlib.h>
//链表结点
struct LinkNode{
void *data;
struct LinkNode *next;
};
//链表
struct _Linklist{
struct LinkNode header;
int size; //链表结点的数目
};
typedef void *LinkList;
#ifdef __cplusplus
extern "C" {
#endif
//初始化链表
LinkList Init_LinkList();
//指定位置插入
int InsertByPos_LinkList(LinkList list, int pos, void *data);
//头插
int PushFront_LinkList(LinkList list, void *data);
//尾插
int PushBack_LinkList(LinkList list, void *data);
//在指定值的前面插入
int InsertByVal_LinkList(LinkList list, void *oldval, void *newval, int(*isequal)(void*,void*));
//指定位置删除
int RemoveByPos_LinkList(LinkList list, int pos);
//根据值删除
int RemoveByVal_LinkList(LinkList list, void *data, int(*compare)(void *, void *));
//头删
void PopFront_LinkList(LinkList list);
//尾删
void PopBack_LinkList(LinkList list);
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *));
//销毁
void Destroy_LinkList(LinkList list);
#ifdef __cplusplus
}
#endif
头文件实现:
#include"LinkList.h"
//初始化链表
LinkList Init_LinkList(){
struct _Linklist *list = malloc(sizeof(struct _Linklist));
if (NULL == list){
return NULL;
}
list->header.data = NULL;
list->header.next = NULL;
list->size = 0;
return list;
}
//指定位置插入 0代表插入到第一个位置
int InsertByPos_LinkList(LinkList list, int pos, void *data){
if (NULL == list){
return -1;
}
if (NULL == data){
return -2;
}
struct _Linklist *llist = (struct _Linklist *)list;
if (pos < 0 || pos > llist->size){
pos = llist->size;
}
//辅助指针变量
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos;i ++){
pCurrent = pCurrent->next;
}
//创建新结点
struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
newnode->data = data;
newnode->next = NULL;
//新结点入链表
newnode->next = pCurrent->next;
pCurrent->next = newnode;
//size
llist->size++;
return 0;
}
//头插
int PushFront_LinkList(LinkList list, void *data){
return InsertByPos_LinkList(list, 0, data);
}
//尾插
int PushBack_LinkList(LinkList list, void *data){
if (NULL == list){
return -1;
}
struct _Linklist *llist = (struct _Linklist *)list;
return InsertByPos_LinkList(list,llist->size - 1,data);
}
//在指定值的前面插入
int InsertByVal_LinkList(LinkList list, void *oldval, void *newval, int(*isequal)(void*, void*)){
if(NULL ==list){
return -1;
}
if (NULL == oldval){
return -2;
}
if (NULL == newval){
return -3;
}
if (NULL == isequal){
return -4;
}
struct _Linklist *llist = (struct _Linklist *)list;
//辅助指针变量
struct LinkNode *pPrev = &(llist->header);
struct LinkNode *pCurrent = pPrev->next;
while (pCurrent != NULL){
if (isequal(pCurrent->data, oldval)){
//创建新结点
struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
newnode->data = newval;
newnode->next = NULL;
//新结点入链表
pPrev->next = newnode;
newnode->next = pCurrent;
llist->size++;
break;
}
pPrev = pCurrent;
pCurrent = pCurrent->next;
}
return 0;
}
//指定位置删除
int RemoveByPos_LinkList(LinkList list, int pos){
if (NULL == list){
return -1;
}
struct _Linklist *llist = (struct _Linklist *)list;
if (llist->size == 0){
return 0;
}
if (pos < 0 || pos > llist->size - 1){
return 0;
}
//辅助指针变量
//找到待删除结点的前一个结点
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos;i ++){
pCurrent = pCurrent->next;
}
//缓存下待删除结点
struct LinkNode *pDel = pCurrent->next;
//重新建立待删除结点的前驱后继结点关系
pCurrent->next = pDel->next;
//删除结点内存
free(pDel);
pDel = NULL;
llist->size--;
return 0;
}
//根据值删除
int RemoveByVal_LinkList(LinkList list, void *data, int(*compare)(void *, void *)){
if (NULL == list){
return -1;
}
if (NULL == data){
return -2;
}
if (NULL == compare){
return -3;
}
struct _Linklist *llist = (struct _Linklist *)list;
//辅助指针变量
struct LinkNode *pPrev = &(llist->header);
struct LinkNode *pCurrent = pPrev->next;
while (pCurrent != NULL){
if (compare(pCurrent->data, data)){
pPrev->next = pCurrent->next;
free(pCurrent);
llist->size--;
break;
}
pPrev = pCurrent;
pCurrent = pPrev->next;
}
return 0;
}
//头删
void PopFront_LinkList(LinkList list){
RemoveByPos_LinkList(list, 0);
}
//尾删
void PopBack_LinkList(LinkList list){
if (NULL == list){
return;
}
struct _Linklist *llist = (struct _Linklist *)list;
RemoveByPos_LinkList(list, llist->size - 1);
}
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *)){
if (NULL == list){
return;
}
if (NULL == foreach){
return;
}
struct _Linklist *llist = (struct _Linklist *)list;
//辅助指针变量
struct LinkNode *pCurrent = llist->header.next;
while (pCurrent != NULL){
foreach(pCurrent->data);
pCurrent = pCurrent->next;
}
}
//销毁
void Destroy_LinkList(LinkList list){
if (NULL == list){
return;
}
struct _Linklist *llist = (struct _Linklist *)list;
//辅助指针变量
struct LinkNode *pCurrent = llist->header.next;
while (pCurrent != NULL){
//缓存下一个结点
struct LinkNode *pNext = pCurrent->next;
//释放当前结点内存
free(pCurrent);
//指针移动到下一个结点的位置
pCurrent = pNext;
}
free(llist);
llist = NULL;
}
测试代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkList.h"
struct Person{
char name[64];
int age;
};
void MyPrint(void *data){
struct Person *person = (struct Person *)data;
printf("Name:%s Age:%d\n", person->name,person->age);
}
int MyCompare(void *d1,void *d2){
struct Person *p1 = (struct Person *)d1;
struct Person *p2 = (struct Person *)d2;
return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}
void test(){
//创建测试数据
struct Person p1 = { "aaa", 10 };
struct Person p2 = { "bbb", 20 };
struct Person p3 = { "ccc", 30 };
struct Person p4 = { "ddd", 40 };
struct Person p5 = { "eee", 50 };
struct Person p6 = { "fff", 60 };
struct Person p7 = { "ggg", 70 };
//初始化链表
LinkList list = Init_LinkList();
//将数据插入链表
InsertByPos_LinkList(list, 0, &p1);
InsertByPos_LinkList(list, 0, &p2);
InsertByPos_LinkList(list, 0, &p3);
InsertByPos_LinkList(list, 1, &p4);
InsertByPos_LinkList(list, 0, &p5);
InsertByPos_LinkList(list, 0, &p6);
//遍历 6 5 3 4 2 1
Foreach_LinkList(list, MyPrint);
printf("-------------------\n");
printf("在name为ccc,age为30的数据前面插入:\n");
InsertByVal_LinkList(list, &p3, &p7, MyCompare);
Foreach_LinkList(list, MyPrint);
printf("删除位置4的数据:\n");
RemoveByPos_LinkList(list,4);
Foreach_LinkList(list, MyPrint);
printf("删除name为ggg age为70的数据:\n");
RemoveByVal_LinkList(list, &p7, MyCompare);
Foreach_LinkList(list, MyPrint);
//销毁链表
Destroy_LinkList(list);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
链表版本二:通过修改指针的指向的区域的大小,实现数据链接,给用户使用
头文件:
#pragma once
#include<stdlib.h>
//链表小节点
//目的 : 第一,让用户数据包含 第二,我需要把用户指针类型转换成struct LinkNode*类型
struct LinkNode{
struct LinkNode *next;
};
//链表结构体
struct LList{
struct LinkNode header;
int size;
};
typedef void *LinkList;
//初始化
LinkList Init_LinkList();
//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data);
//位置删除
void RemoveByPos_LinkList(LinkList list, int pos);
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *));
//销毁
void Destroy_LinkList(LinkList list);
头文件实现:
#include"LinkList.h"
//初始化
LinkList Init_LinkList(){
struct LList *list = malloc(sizeof(struct LList));
if (NULL == list){
return NULL;
}
list->header.next = NULL;
list->size = 0;
return list;
}
//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data){
if (NULL == list){
return;
}
if (NULL == data){
return;
}
struct LList *llist = (struct LList *)list;
if (pos < 0 || pos >llist->size){
pos = llist->size;
}
//查找pos位置前一个位置的节点
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos;i ++){
pCurrent = pCurrent->next;
}
//将新节点插入到链表
data->next = pCurrent->next;
pCurrent->next = data;
llist->size++;
}
//位置删除
void RemoveByPos_LinkList(LinkList list, int pos){
if (NULL ==list){
return;
}
struct LList *llist = (struct LList *)list;
if (llist->size == 0){
return;
}
if (pos < 0 || pos > llist->size - 1){
return;
}
//找到pos位置的前一个节点
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos; i ++){
pCurrent = pCurrent->next;
}
//缓存下待删除节点
struct LinkNode *pDel = pCurrent->next;
//重新建立待删除的节点前驱后继节点关系
pCurrent->next = pDel->next;
llist->size--;
}
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *)){
if (NULL == list){
return;
}
struct LList *llist = (struct LList *)list;
//辅助指针变量
struct LinkNode *pCurrent = llist->header.next;
while (pCurrent != NULL){
foreach(pCurrent);
pCurrent = pCurrent->next;
}
}
测试函数:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkList.h"
struct Person{
struct LinkNode node;
char name[64];
int age;
};
void MyPrint(void *data){
struct Person *person = (struct Person *)data;
printf("Name:%s Age:%d\n",person->name,person->age);
}
void ChanageValue(void *data){
struct Person *person = (struct Person *)data;
person->age += 100;
}
//#define ISSTACK
void test(){
//创建测试数据
#ifdef ISSTACK
struct Person p1 = { NULL , "aaa", 10 };
struct Person p2 = { NULL , "bbb", 20 };
struct Person p3 = { NULL , "ccc", 30 };
struct Person p4 = { NULL , "ddd", 40 };
struct Person p5 = { NULL , "eee", 50 };
#else
struct Person *p1 = malloc(sizeof(struct Person));
struct Person *p2 = malloc(sizeof(struct Person));
struct Person *p3 = malloc(sizeof(struct Person));
struct Person *p4 = malloc(sizeof(struct Person));
struct Person *p5 = malloc(sizeof(struct Person));
strcpy(p1->name, "aaa");
strcpy(p2->name, "bbb");
strcpy(p3->name, "ccc");
strcpy(p4->name, "ddd");
strcpy(p5->name, "eee");
p1->age = 10;
p2->age = 20;
p3->age = 30;
p4->age = 40;
p5->age = 50;
#endif
//初始化链表
LinkList list = Init_LinkList();
#ifdef ISSTACK
//数据插入到链表
Insert_LinkList(list, 0, (struct LinkNode *)&p1);
Insert_LinkList(list, 0, (struct LinkNode *)&p2);
Insert_LinkList(list, 0, (struct LinkNode *)&p3);
Insert_LinkList(list, 0, (struct LinkNode *)&p4);
Insert_LinkList(list, 0, (struct LinkNode *)&p5);
#else
Insert_LinkList(list, 0, (struct LinkNode *)p1);
Insert_LinkList(list, 0, (struct LinkNode *)p2);
Insert_LinkList(list, 0, (struct LinkNode *)p3);
Insert_LinkList(list, 0, (struct LinkNode *)p4);
Insert_LinkList(list, 0, (struct LinkNode *)p5);
#endif
//遍历
Foreach_LinkList(list, MyPrint);
//删除2号位置
printf("------------------\n");
RemoveByPos_LinkList(list, 3);
Foreach_LinkList(list, MyPrint);
//遍历修改数据
printf("---------------------\n");
//Foreach_LinkList(list, ChanageValue);
//Foreach_LinkList(list, MyPrint);
//销毁链表
Destroy_LinkList(list);
free(p1);
free(p2);
free(p3);
free(p4);
free(p5);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
以链表为底层容器实现栈
头文件:
容器头文件:
#pragma once
#include<stdlib.h>
//链表小节点
//目的 : 第一,让用户数据包含 第二,我需要把用户指针类型转换成struct LinkNode*类型
struct LinkNode{
struct LinkNode *next;
};
//链表结构体
struct LList{
struct LinkNode header;
int size;
};
typedef void *LinkList;
//初始化
LinkList Init_LinkList();
//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data);
//位置删除
void RemoveByPos_LinkList(LinkList list, int pos);
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *));
//根据位置获得值
void *Get_LinkList(LinkList list,int pos);
int Size_LinkList(LinkList list);
//销毁
void Destroy_LinkList(LinkList list);
栈头文件:
#pragma once
#include"LinkList.h"
struct StackNode{
struct LinkNode node;
};
typedef void *LinkStack;
//初始化
LinkStack Init_LinkStack();
//入栈
void Push_LinkStack(LinkStack stack, void *data);
//出栈
void Pop_LinkStack(LinkStack stack);
//获得栈顶元素
void *Top_LinkStack(LinkStack stack);
//大小
int Size_LinkStack(LinkStack stack);
//销毁栈
void Destroy_LinkStack(LinkStack stack);
头文件实现:
容器头文件实现:
#include"LinkList.h"
//初始化
LinkList Init_LinkList(){
struct LList *list = malloc(sizeof(struct LList));
if (NULL == list){
return NULL;
}
list->header.next = NULL;
list->size = 0;
return list;
}
//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data){
if (NULL == list){
return;
}
if (NULL == data){
return;
}
struct LList *llist = (struct LList *)list;
if (pos < 0 || pos >llist->size){
pos = llist->size;
}
//查找pos位置前一个位置的节点
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos;i ++){
pCurrent = pCurrent->next;
}
//将新节点插入到链表
data->next = pCurrent->next;
pCurrent->next = data;
llist->size++;
}
//位置删除
void RemoveByPos_LinkList(LinkList list, int pos){
if (NULL ==list){
return;
}
struct LList *llist = (struct LList *)list;
if (llist->size == 0){
return;
}
if (pos < 0 || pos > llist->size - 1){
return;
}
//找到pos位置的前一个节点
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos; i ++){
pCurrent = pCurrent->next;
}
//缓存下待删除节点
struct LinkNode *pDel = pCurrent->next;
//重新建立待删除的节点前驱后继节点关系
pCurrent->next = pDel->next;
llist->size--;
}
//根据位置获得值
void *Get_LinkList(LinkList list, int pos){
if (NULL == list){
return NULL;
}
struct LList *llist = (struct LList *)list;
if (pos < 0 || pos > llist->size - 1){
return NULL;
}
//辅助指针变量
struct LinkNode *pCurrent = &(llist->header);
for (int i = 0; i < pos; i++){
pCurrent = pCurrent->next;
}
return pCurrent->next;
}
int Size_LinkList(LinkList list){
if (NULL == list){
return -1;
}
struct LList *llist = (struct LList *)list;
return llist->size;
}
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *)){
if (NULL == list){
return;
}
struct LList *llist = (struct LList *)list;
//辅助指针变量
struct LinkNode *pCurrent = llist->header.next;
while (pCurrent != NULL){
foreach(pCurrent);
pCurrent = pCurrent->next;
}
}
//销毁
void Destroy_LinkList(LinkList list){
if (NULL == list){
return;
}
free(list);
list = NULL;
}
栈头文件实现:
#include"LinkStack.h"
//初始化
LinkStack Init_LinkStack(){
return Init_LinkList();
}
//入栈
void Push_LinkStack(LinkStack stack, void *data){
Insert_LinkList(stack, 0, data);
}
//出栈
void Pop_LinkStack(LinkStack stack){
RemoveByPos_LinkList(stack, 0);
}
//获得栈顶元素
void *Top_LinkStack(LinkStack stack){
return Get_LinkList(stack, 0);
}
//大小
int Size_LinkStack(LinkStack stack){
return Size_LinkList(stack);
}
//销毁栈
void Destroy_LinkStack(LinkStack stack){
Destroy_LinkList(stack);
}
测试文件
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkStack.h"
struct Person{
struct StackNode node;
char name[64];
int age;
};
void test(){
//创建测试数据
struct Person p1 = { NULL, "aaa", 10 };
struct Person p2 = { NULL, "bbb", 20 };
struct Person p3 = { NULL, "ccc", 30 };
struct Person p4 = { NULL, "ddd", 40 };
struct Person p5 = { NULL, "eee", 50 };
//初始化栈
LinkStack stack = Init_LinkStack();
//数据入栈
Push_LinkStack(stack , &p1);
Push_LinkStack(stack, &p2);
Push_LinkStack(stack, &p3);
Push_LinkStack(stack, &p4);
Push_LinkStack(stack, &p5);
//输出栈中元素
while (Size_LinkStack(stack) > 0){
//获得栈顶元素
struct Person *person = (struct Person*)Top_LinkStack(stack);
//输出元素
printf("Name:%s Age:%d\n",person->name,person->age);
//弹出栈顶元素
Pop_LinkStack(stack);
}
printf("Size%d\n",Size_LinkStack(stack));
//销毁栈
Destroy_LinkStack(stack);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
二叉树
二叉树性质
n 性质1: 在二叉树的第i层上至多有2i-1个结点(i>0)
n 性质2: 深度为k的二叉树至多有2k-1个结点(k>0)
n 性质3: 对于任何一棵二叉树,若度为2的结点数有n2个,则叶子数(n0)必定为n2+1 (即n0=n2+1)
二叉树的递归遍历源码:分为先序遍历:根 左 右 ;中序遍历:左 根 右;后续遍历:左 右 根
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//二叉树节点
struct BiNode{
char ch;
struct BiNode *lchild;
struct BiNode *rchild;
};
//二叉树的递归遍历先序
void recursion(struct BiNode *root){
if (NULL == root){
return;
}
//再访问左子树
recursion(root->lchild);//printf 先序遍历
//再访问右子树
recursion(root->rchild);// printf 中顺序遍历
//先访问根节点
printf("%c ", root->ch);// printf 后续遍历
}
void test(){
//二叉树节点
struct BiNode node1 = { 'A', NULL, NULL };
struct BiNode node2 = { 'B', NULL, NULL };
struct BiNode node3 = { 'C', NULL, NULL };
struct BiNode node4 = { 'D', NULL, NULL };
struct BiNode node5 = { 'E', NULL, NULL };
struct BiNode node6 = { 'F', NULL, NULL };
struct BiNode node7 = { 'G', NULL, NULL };
struct BiNode node8 = { 'H', NULL, NULL };
node1.lchild = &node2;
node1.rchild = &node6;
node2.rchild = &node3;
node3.lchild = &node4;
node3.rchild = &node5;
node6.rchild = &node7;
node7.lchild = &node8;
//遍历二叉树
recursion(&node1);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
通过栈实现二叉树的非递归遍历:
见数据结构 栈的实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"SeqStack.h"
#include<stdbool.h>
//二叉树节点
struct BiNode{
char ch;
struct BiNode *lchild;
struct BiNode *rchild;
};
struct Info{
struct BiNode *node;
bool flag;
};
struct Info *CreateInfo(struct BiNode *node,bool flag){
struct Info *info = malloc(sizeof(struct Info));
info->node = node;
info->flag = flag;
return info;
}
void nonrecursion(struct BiNode *root){
//初始化stack
void *stack = Init_SeqStack();
//1. 先把根节点入stack
Push_SeqStack(stack, CreateInfo(root, false));
while (Size_SeqStack(stack) > 0){
//2. 获得stack顶元素
struct Info *info = (struct Info *)Top_SeqStack(stack);
Pop_SeqStack(stack);
//3. 判断当前节点的flag是否为true,true:直接输出。false:左子树和右子树分别压stack,当前节点二次入stack
if(info->flag){
printf("%c ",info->node->ch);
free(info);
continue;
}
//右子树入stack
if (info->node->rchild != NULL){
Push_SeqStack(stack, CreateInfo(info->node->rchild, false));
}
//根节点入stack
info->flag = true;
Push_SeqStack(stack, info);
//左子树入stack
if (info->node->lchild != NULL){
Push_SeqStack(stack, CreateInfo(info->node->lchild, false));
}
}
}
void test(){
//二叉树节点
struct BiNode node1 = { 'A', NULL, NULL };
struct BiNode node2 = { 'B', NULL, NULL };
struct BiNode node3 = { 'C', NULL, NULL };
struct BiNode node4 = { 'D', NULL, NULL };
struct BiNode node5 = { 'E', NULL, NULL };
struct BiNode node6 = { 'F', NULL, NULL };
struct BiNode node7 = { 'G', NULL, NULL };
struct BiNode node8 = { 'H', NULL, NULL };
node1.lchild = &node2;
node1.rchild = &node6;
node2.rchild = &node3;
node3.lchild = &node4;
node3.rchild = &node5;
node6.rchild = &node7;
node7.lchild = &node8;
nonrecursion(&node1);
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}
求二叉数的叶子节点函数:
void caculateLeafNums(struct BiNode *root,int *num){
if (NULL == root){
return;
}
if (root->lchild == NULL && root->rchild == NULL){
(*num)++;
}
//遍历左子树
caculateLeafNums(root->lchild, num);
//遍历右子树
caculateLeafNums(root->rchild, num);
}
二叉树的拷贝、释放、二叉树高度函数:
//拷贝二叉树
struct BiNode *copyTree(struct BiNode *root){
if (NULL == root){
return NULL;
}
//递归拷贝左子树
struct BiNode *lchild = copyTree(root->lchild);
//递归拷贝右子树
struct BiNode *rchild = copyTree(root->rchild);
//拷贝当前节点
struct BiNode *newnode = malloc(sizeof(struct BiNode));
printf("%c ",root->ch);
newnode->ch = root->ch;
newnode->lchild = lchild;
newnode->rchild = rchild;
return newnode;
}
//释放二叉树内存
void freeSpace(struct BiNode *root){
if (NULL == root){
return;
}
//释放左子树
freeSpace(root->lchild);
//释放右子树
freeSpace(root->rchild);
//释放根节点
free(root);
}
//递归遍历
void foreach(struct BiNode *root){
if (NULL == root){
return;
}
printf("%c ",root->ch);
foreach(root->lchild);
foreach(root->rchild);
}
//求树的高度
int caculateTreeHeight(struct BiNode *root){
if (NULL == root){
return 0;
}
//求左子树的高度
int lheight = caculateTreeHeight(root->lchild);
//求右子树的高度
int rheight = caculateTreeHeight(root->rchild);
int height = lheight > rheight ? lheight + 1 : rheight + 1;
return height;
}