1.栈
1.1栈的基本概念
栈是一个线性表,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的
线性表而已。在线性表的表尾进行插入和删除操作,当对象为栈的时候,这里表尾是
指栈顶,而不是栈底。栈的特殊之处在于限制了这个线性表的插入和删除的位置,它
始终只在栈顶进行。这也就使得:栈底是固定的,最先进栈的只能在栈底。也就是说
这是一种先进后出的模型。
1.2栈的顺序存储
栈的顺序存储结构简称顺序栈,它是运算受限制的顺序表。顺序栈的存储结构是:
利用一组地址连续的的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针
top只是栈顶元素在顺序表中的位置。
(其中)当使用栈的顺序存储的时候,栈的首元素代表的是栈底元素。
1.3 栈顶顺序存储的实现
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#define MAX 1024
struct SStack
{
void* buffer[MAX];
int m_size;
};
struct Person
{
char name[64];
int age;
};
void* init_Stack()
{
struct SStack* m_stack = malloc(sizeof(struct SStack));
if (m_stack == NULL)
return NULL;
memset(m_stack->buffer, 0, sizeof(void*) * MAX);
m_stack->m_size = 0;
return m_stack;
}
void push_Stack(struct SStack* m_stack,void* value)
{
if (m_stack == NULL || value == NULL)
return;
struct SStack* stack1 = m_stack;
if (stack1->m_size == MAX)
return;
stack1->buffer[stack1->m_size] = value;
stack1->m_size++;
}
void* pop_Stack(struct SStack* m_stack)
{
if (m_stack == NULL)
return NULL;
struct SStack* stack1 = m_stack;
if (stack1->m_size == 0)
return NULL;
void* tempValue = stack1->buffer[stack1->m_size - 1];
stack1->buffer[stack1->m_size - 1] = NULL;
stack1->m_size--;
return tempValue;
}
void* top_Stack(struct SStack* m_stack)
{
if (m_stack == NULL)
return NULL;
struct SStack* stack1 = m_stack;
if (stack1->m_size == 0)
return NULL;
return stack1->buffer[stack1->m_size - 1];
}
int size_Stack(struct SStack* m_stack)
{
if (m_stack == NULL)
return 0;
struct SStack* stack1 = m_stack;
return stack1->m_size;
}
int empty_Stack(struct SStack* m_stack)
{
if (m_stack == NULL)
return -1;
struct SStack* stack1 = m_stack;
if (stack1->m_size == 0)
return 1;
return 0;
}
void destroy_Stack(struct SStack* m_stack)
{
if (m_stack == NULL)
return;
free(m_stack);
m_stack = NULL;
}
void myPrint(void* value)
{
struct Person* p1 = value;
printf("姓名:%s,年龄:%d\n", p1->name, p1->age);
}
void test01()
{
struct SStack* m_stack = init_Stack();
struct Person p1 = { "张三",22 };
struct Person p2 = { "李四",23 };
struct Person p3 = { "王五",21 };
struct Person p4 = { "赵六",19 };
struct Person p5 = { "孙起",20 };
push_Stack(m_stack, &p1);
push_Stack(m_stack, &p2);
push_Stack(m_stack, &p3);
push_Stack(m_stack, &p4);
push_Stack(m_stack, &p5);
printf("栈内元素个数为:%d\n", size_Stack(m_stack));
myPrint(pop_Stack(m_stack));
myPrint(pop_Stack(m_stack));
myPrint(pop_Stack(m_stack));
myPrint(pop_Stack(m_stack));
myPrint(pop_Stack(m_stack));
printf("栈内元素个数为:%d\n", size_Stack(m_stack));
if (empty_Stack(m_stack) == 1)
printf("栈已经为空!");
else
printf("栈不为空/传入参数有问题!");
destroy_Stack(m_stack);
}
int main()
{
test01();
return 0;
}
1.4栈的链式存储
栈的链式存储结构简称链栈。由于单链表有头指针,而栈顶指针也是必须的,因此,
可以将二者何在一起使用,比较好的办法就是把栈顶放在单链表的头部。另外都已经
有了栈顶在头部了,单链表中比较常用的头结点也就失去了意义,通常对于链栈来说
,是不需要头结点的。
1.5 栈的链式存储的实现
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
struct LinkNode
{
struct LinkNode* next;
};
struct LinkStack
{
struct LinkNode shead;
int m_size;
};
struct Person
{
struct LinkNode* next;
char namr[64];
int age;
};
void* init_Linkstack()
{
struct LinkStack* m_stack = malloc(sizeof(struct LinkStack));
if (m_stack == NULL)
return NULL;
m_stack->m_size = 0;
m_stack->shead.next = NULL;
return m_stack;
}
void push_LinkStack(struct LinkStack* m_stack,void * value)
{
if (m_stack == NULL || value == NULL)
return;
struct LinkNode* m_value = value;
m_value->next = m_stack->shead.next;
m_stack->shead.next = m_value;
m_stack->m_size++;
}
void pop_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL || m_stack->m_size == 0)
return;
struct LinkNode* pCurrent = m_stack->shead.next;
m_stack->shead.next = pCurrent->next;
m_stack->m_size--;
}
void* top_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL || m_stack->m_size == 0)
return NULL;
return m_stack->shead.next;
}
int empty_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL)
return -1;
if (m_stack->m_size == 0)
return 1;
return 0;
}
int size_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL)
return -1;
return m_stack->m_size;
}
void destroy_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL)
return;
free(m_stack);
m_stack = NULL;
}
void test01()
{
struct LinkStack* m_stack = init_Linkstack();
struct Person p1 = { NULL,"张三",22 };
struct Person p2 = { NULL,"李四",23 };
struct Person p3 = { NULL,"王五",21 };
struct Person p4 = { NULL,"赵六",19 };
struct Person p5 = { NULL,"孙起",20 };
push_LinkStack(m_stack, &p1);
push_LinkStack(m_stack, &p2);
push_LinkStack(m_stack, &p3);
push_LinkStack(m_stack, &p4);
push_LinkStack(m_stack, &p5);
printf("栈内元素个数为:%d\n", size_LinkStack(m_stack));
while (empty_LinkStack(m_stack) == 0)
{
struct Person* temp1 = top_LinkStack(m_stack);
printf("姓名:%s,年龄:%d\n",temp1->namr,temp1->age);
pop_LinkStack(m_stack);
}
printf("栈内元素个数为:%d\n", size_LinkStack(m_stack));
if (empty_LinkStack(m_stack) == 1)
printf("栈已经为空!");
else
printf("栈不为空/传入参数有问题!");
destroy_LinkStack(m_stack);
}
int main()
{
test01();
return 0;
}
1.6 案例:就近匹配(编译器可以在()不匹配的时候报错,运用了栈的原理)
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
struct LinkNode
{
struct LinkNode* next;
};
struct LinkStack
{
struct LinkNode shead;
int m_size;
};
void* init_Linkstack()
{
struct LinkStack* m_stack = malloc(sizeof(struct LinkStack));
if (m_stack == NULL)
return NULL;
m_stack->m_size = 0;
m_stack->shead.next = NULL;
return m_stack;
}
void push_LinkStack(struct LinkStack* m_stack,void * value)
{
if (m_stack == NULL || value == NULL)
return;
struct LinkNode* m_value = value;
m_value->next = m_stack->shead.next;
m_stack->shead.next = m_value;
m_stack->m_size++;
}
void pop_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL || m_stack->m_size == 0)
return;
struct LinkNode* pCurrent = m_stack->shead.next;
m_stack->shead.next = pCurrent->next;
m_stack->m_size--;
}
void* top_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL || m_stack->m_size == 0)
return NULL;
return m_stack->shead.next;
}
int empty_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL)
return -1;
if (m_stack->m_size == 0)
return 1;
return 0;
}
int size_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL)
return -1;
return m_stack->m_size;
}
void destroy_LinkStack(struct LinkStack* m_stack)
{
if (m_stack == NULL)
return;
free(m_stack);
m_stack = NULL;
}
void test01()
{
struct LinkStack* m_stack = init_Linkstack();
char ch[64] = "3*1+(6*2)*(8/4)6-2(";
char temparr[64];
int i;
for (i = 0; i < strlen(ch); ++i)
{
memset(temparr, 0, 64);
memcpy(temparr, ch, 64);
if (temparr[i] == '(')
{
push_LinkStack(m_stack, &temparr[i]);
}
if (temparr[i] == ')')
{
if (top_LinkStack(m_stack) == NULL)
{
printf("匹配失败!(错误1:先有的)符号):\n");
printf("%s\n", ch);
if (i != (strlen(ch) - 1))
{
for (int j = 0; j < i; j++)
{
printf(" ");
}
printf("|\n");
}
return;
}
pop_LinkStack(m_stack);
}
}
if(empty_LinkStack(m_stack) == 0)
{
printf("字符串不合格!(错误2:仅有(符号):\n");
printf("%s\n", ch);
if (i != (strlen(ch) - 1))
{
for (int j = 0; j < i - 1; j++)
{
printf(" ");
}
printf("|\n");
}
destroy_LinkStack(m_stack);
return;
}
else
{
destroy_LinkStack(m_stack);
return;
}
}
int main()
{
test01();
return 0;
}
2.队列
2.1队列基本概念
队列是一种特殊的受限制的线性表。 队列是只允许在一端进行插入操作,而在
另一端进行删除操作的线性表。它是一种先进先出的特殊的的线性表,简称FIFO。
允许插入的一端为队尾(尾插),允许删除的一端为队头(头删)。队列不允许在
中间部位进行操作,仅仅允许在队头和队尾进行相应的操作。
2.2 队列的顺序存储
由之前写好的动态数组的代码直接封装即可,很多功能的实现用之前动态数组中
写好的功能就行。
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#define MAX 1024
typedef void * seqQueue;
struct dynamicArray
{
void ** pAddr;
int m_Capacity;
int m_Size;
};
struct dynamicArray * init_dynamicArray(int capacity);
void insert_dynamicArray(struct dynamicArray * arr, int pos, void * data);
void foreach_dynamicArray(struct dynamicArray * arr, void(*myPrint)(void *));
void removeByPos_dynamicArray(struct dynamicArray * arr, int pos);
void removeByValue_dynamicArray(struct dynamicArray * arr, void * data, int(*myCompare)(void *, void *));
void destroy_dynamicArray(struct dynamicArray * arr);
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);
int isEmpty_SeqQueue(seqQueue queue);
void destroy_SeqQueue(seqQueue queue);
struct Person
{
char name[64];
int age;
};
void test01()
{
seqQueue myQueue = init_SeqQueue();
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 };
push_SeqQueue(myQueue, &p1);
push_SeqQueue(myQueue, &p2);
push_SeqQueue(myQueue, &p3);
push_SeqQueue(myQueue, &p4);
push_SeqQueue(myQueue, &p5);
printf("队列大小为:%d\n", size_SeqQueue(myQueue));
while (isEmpty_SeqQueue(myQueue) == 0)
{
struct Person * pFront = front_SeqQueue(myQueue);
printf("队头元素姓名:%s 年龄:%d \n", pFront->name, pFront->age);
struct Person * pBack = back_SeqQueue(myQueue);
printf("队尾元素姓名:%s 年龄:%d \n", pBack->name, pBack->age);
pop_SeqQueue(myQueue);
}
printf("队列大小为:%d\n", size_SeqQueue(myQueue));
destroy_SeqQueue(myQueue);
myQueue = NULL;
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
struct dynamicArray * init_dynamicArray(int capacity)
{
struct dynamicArray * array = malloc(sizeof(struct dynamicArray));
if (array == NULL)
{
return NULL;
}
array->m_Capacity = capacity;
array->m_Size = 0;
array->pAddr = malloc(sizeof(void *)* capacity);
if (array->pAddr == NULL)
{
return NULL;
}
return array;
}
void insert_dynamicArray(struct dynamicArray * arr, int pos, void * data)
{
if (arr == NULL)
return;
if (data == NULL)
return;
if (pos < 0 || pos > arr->m_Size)
pos = arr->m_Size;
if (arr->m_Size >= arr->m_Capacity)
{
int newCapacity = arr->m_Capacity * 2;
void ** newSpace = malloc(sizeof (void *)* newCapacity);
memcpy(newSpace, arr->pAddr, sizeof(void*)* arr->m_Capacity);
free(arr->pAddr);
arr->pAddr = newSpace;
arr->m_Capacity = newCapacity;
}
for (int i = arr->m_Size - 1; i >= pos; i--)
{
arr->pAddr[i + 1] = arr->pAddr[i];
}
arr->pAddr[pos] = data;
arr->m_Size++;
}
void foreach_dynamicArray(struct dynamicArray * arr, void(*myPrint)(void *))
{
if (arr == NULL)
return;
if (myPrint == NULL)
return;
for (int i = 0; i < arr->m_Size; i++)
myPrint(arr->pAddr[i]);
}
void removeByPos_dynamicArray(struct dynamicArray * arr, int pos)
{
if (arr == NULL)
return;
if (pos < 0 || pos >arr->m_Size - 1)
return;
for (int i = pos; i < arr->m_Size - 1; i++)
{
arr->pAddr[i] = arr->pAddr[i + 1];
}
arr->m_Size--;
}
void removeByValue_dynamicArray(struct dynamicArray * arr, void * data, int(*myCompare)(void *, void *))
{
if (arr == NULL)
return;
if (data == NULL)
return;
for (int i = 0; i < arr->m_Size; i++)
{
if (myCompare(arr->pAddr[i], data))
{
removeByPos_dynamicArray(arr, i);
break;
}
}
}
void destroy_dynamicArray(struct dynamicArray * arr)
{
if (arr == NULL)
return;
if (arr->pAddr != NULL)
{
free(arr->pAddr);
arr->pAddr = NULL;
}
free(arr);
arr = NULL;
}
seqQueue init_SeqQueue()
{
struct dynamicArray * array = init_dynamicArray(MAX);
return array;
}
void push_SeqQueue(seqQueue queue, void * data)
{
if (queue == NULL)
return;
if (data == NULL)
return;
struct dynamicArray * array = queue;
if (array->m_Size >= MAX)
return;
insert_dynamicArray(array, array->m_Size, data);
}
void pop_SeqQueue(seqQueue queue)
{
if (queue == NULL)
return;
struct dynamicArray * array = queue;
if (array->m_Size <= 0)
return;
removeByPos_dynamicArray(array, 0);
}
void * front_SeqQueue(seqQueue queue)
{
if (queue == NULL)
return NULL;
struct dynamicArray * array = queue;
return array->pAddr[0];
}
void * back_SeqQueue(seqQueue queue)
{
if (queue == NULL)
return NULL;
struct dynamicArray * array = queue;
return array->pAddr[array->m_Size - 1];
}
int size_SeqQueue(seqQueue queue)
{
if (queue == NULL)
return -1;
struct dynamicArray * array = queue;
return array->m_Size;
}
int isEmpty_SeqQueue(seqQueue queue)
{
if (queue == NULL)
return -1;
struct dynamicArray * array = queue;
if (array->m_Size == 0)
return 1;
return 0;
}
void destroy_SeqQueue(seqQueue queue)
{
if (queue == NULL)
return ;
destroy_dynamicArray(queue);
queue = NULL;
}
2.3 队列的链式存储
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
struct Person
{
char name[64];
int age;
};
struct LinkQueue
{
struct LinkQueue* next;
void* data;
int m_size;
};
void* init_Queue()
{
struct LinkQueue* m_queue = malloc(sizeof(struct LinkQueue));
if (m_queue == NULL)
return NULL;
m_queue->data = NULL;
m_queue->next = NULL;
m_queue->m_size = 0;
return m_queue;
}
void push_Queue(struct LinkQueue* m_queue,void* value)
{
if (m_queue == NULL || value == NULL)
return;
struct LinkQueue* m_tail = m_queue;
for (int i = 0; i < m_queue->m_size; ++i)
{
m_tail = m_tail->next;
}
struct LinkQueue* new_Value = malloc(sizeof(struct LinkQueue));
m_tail->next = new_Value;
new_Value->data = value;
new_Value->next = NULL;
m_queue->m_size++;
}
void pop_Queue(struct LinkQueue* m_queue)
{
if (m_queue == NULL)
return;
if (m_queue->m_size == 0)
return;
struct LinkQueue* pCurrent = malloc(sizeof(struct LinkQueue));
pCurrent = m_queue->next;
m_queue->next = pCurrent->next;
m_queue->m_size--;
free(pCurrent);
pCurrent = NULL;
}
void* front_Queue(struct LinkQueue* m_queue)
{
if (m_queue == NULL)
return NULL;
if (m_queue->m_size == 0)
return NULL;
struct LinkQueue* pCurrent = m_queue->next;
return pCurrent->data;
}
void* back_Queue(struct LinkQueue* m_queue)
{
if (m_queue == NULL)
return NULL;
if (m_queue->m_size == 0)
return NULL;
struct LinkQueue* m_tail = m_queue;
for (int i = 0; i < m_queue->m_size; ++i)
{
m_tail = m_tail->next;
}
return m_tail->data;
}
int size_Queue(struct LinkQueue* m_queue)
{
if (m_queue == NULL)
return -1;
return m_queue->m_size;
}
int empty_Queue(struct LinkQueue* m_queue)
{
if (m_queue == NULL)
return -1;
if (m_queue->m_size == 0)
return 1;
return 0;
}
void destroy(struct LinkQueue* m_queue)
{
if (m_queue == NULL)
return;
free(m_queue);
m_queue = NULL;
}
void test01()
{
struct LinkQueue* m_queue = init_Queue();
struct Person p1 = {"张三",22 };
struct Person p2 = {"李四",23 };
struct Person p3 = {"王五",21 };
struct Person p4 = {"赵六",19 };
struct Person p5 = {"孙起",20 };
push_Queue(m_queue, &p1);
push_Queue(m_queue, &p2);
push_Queue(m_queue, &p3);
push_Queue(m_queue, &p4);
push_Queue(m_queue, &p5);
while (empty_Queue(m_queue) == 0)
{
pop_Queue(m_queue);
if (m_queue->m_size == 0)
break;
struct Person* temp1 = front_Queue(m_queue);
printf("队头元素的姓名:%s,年龄:%d\n", temp1->name, temp1->age);
struct Person* temp2 = back_Queue(m_queue);
printf("队尾元素的姓名:%s,年龄:%d\n", temp2->name, temp2->age);
printf("队内的元素个数为:%d\n", size_Queue(m_queue));
}
destroy(m_queue);
}
int main()
{
test01();
return 0;
}