目录
栈,一种特殊的线性表,特殊在于只允许在固定的一端进行插入删除数据,插入和删除数据的一端是栈顶,另一端是栈底,已经在栈中的数据满足Fist In Last Out的原则。
压栈:栈顶插入数据
出栈:栈顶弹出数据
总体而言,用顺序表和链表实现都可以,但是由于栈只支持在栈顶插入删除数据,且要满足后进先出,而顺序表尾插尾删的效率比链表高,(顺序表唯一的缺点在这就是扩容有性能和空间的消耗)同时也满足后进先出的原则,所以选择顺序表实现好!
有人可能会说用链表,然后定义一个尾指针,这样尾插效率不是也很高吗?
答:定义一个尾指针,链表的插入时很方便,但是尾删呐??
其实顺序表,双向循环链表,头上操作单链表都行,但是由于顺序表命中率高的优点,还是选择顺序表。
- 选择哪一个方式初始化top都可以,但是记得做到和后面的push等做到统一。
- 建议再主函数内判空操作不直接自己if(ps->top==0)等,因为这个内部怎么实现的不一定是初始化为ps->top=0,而是建议调用函数去判空if(StackEmpty(&ST))
- void StackInit(Stack* ps)
- {
- assert(ps);
- ps->a = NULL;
- ps->top = ps->capacity = 0;
- }
- void StackPush(Stack* ps, STDateType x)
- {
- assert(ps);
-
- if(ps->top == ps->capacity)
- {
- int newcapacity = ps->capacity == 0 ? 4 : ps->capacity*2;
- STDateType* temp = (STDateType*)realloc(ps->a, sizeof(STDateType)*newcapacity);
- if (temp == NULL)
- {
- perror("malloc fail.\n");
- exit(-1);
- }
- ps->capacity = newcapacity;
- ps->a = temp;
- }
- ps->a[ps->top] = x;
- ps->top++;
- }
- void StackPop(Stack* ps)
- {
- assert(ps);
- assert(!StackEmpty(ps));
- ps->top--;
- }
- STDateType StackTop(Stack* ps)
- {
- assert(ps);
- assert(!StackEmpty(ps));
- return ps->a[ps->top - 1];
- }
- int StackSize(Stack* ps)
- {
- assert(ps);
- return ps->top;
- }
- bool StackEmpty(Stack* ps)
- {
- assert(ps);
- return ps->top == 0;
- }
- void StackDestory(Stack* ps)
- {
- assert(ps);
- free(ps->a);
- ps->a = NULL;
- ps->top = ps->capacity = 0;
- }
- #define _CRT_SECURE_NO_WARNINGS 1
- #include"stack.h"
- void StackInit(Stack* ps)
- {
- assert(ps);
- ps->a = NULL;
- ps->top = ps->capacity = 0;
- }
-
- void StackPush(Stack* ps, STDateType x)
- {
- assert(ps);
-
- if(ps->top == ps->capacity)
- {
- int newcapacity = ps->capacity == 0 ? 4 : ps->capacity*2;
- STDateType* temp = (STDateType*)realloc(ps->a, sizeof(STDateType)*newcapacity);
- if (temp == NULL)
- {
- perror("malloc fail.\n");
- exit(-1);
- }
- ps->capacity = newcapacity;
- ps->a = temp;
- }
- ps->a[ps->top] = x;
- ps->top++;
- }
-
- void StackPop(Stack* ps)
- {
- assert(ps);
- assert(!StackEmpty(ps));
- ps->top--;
- }
-
- STDateType StackTop(Stack* ps)
- {
- assert(ps);
- assert(!StackEmpty(ps));
- return ps->a[ps->top - 1];
- }
-
- int StackSize(Stack* ps)
- {
- assert(ps);
- return ps->top;
- }
-
- bool StackEmpty(Stack* ps)
- {
- assert(ps);
- return ps->top == 0;
- }
-
-
- void StackDestory(Stack* ps)
- {
- assert(ps);
- free(ps->a);
- ps->a = NULL;
- ps->top = ps->capacity = 0;
- }
- #define _CRT_SECURE_NO_WARNINGS 1
- #include
- #include
- #include
- #include
-
- typedef int STDateType;
- typedef struct Stack
- {
- STDateType* a;
- int top;
- int capacity;
- }Stack;
-
- void StackInit(Stack* ps);
-
- void StackPush(Stack* ps,STDateType x);
-
- void StackPop(Stack* ps);
-
- STDateType StackTop(Stack* ps);
-
- bool StackEmpty(Stack* ps);
-
- int StackSize(Stack* ps);
-
- void StackDestory(Stack* ps);
-
- #define _CRT_SECURE_NO_WARNINGS 1
- #include"stack.h"
-
-
- int main()
- {
- Stack ST;
- StackInit(&ST);
- StackPush(&ST, 1);
- StackPush(&ST, 2);
- StackPush(&ST, 3);
- StackPush(&ST, 4);
- STDateType top = StackTop(&ST);
- printf("top:%d\n", top);
- StackPop(&ST);
- top = StackTop(&ST);
- printf("top:%d\n", top);
- int size = StackSize(&ST);
- printf("size:%d\n", size);
- StackDestory(&ST);
- return 0;
- }
队列是一种特殊的线性表,特殊在只能从一端进行插入操作,另一端进行删除操作,队列具有Fist In First Out的原则。
队尾:进行插入操作的一端,这个过程叫做入队列
队头:进行删除操作的一端,这个过程叫做出队列
抽号机:先来先服务,先给号码排队 (涉及嵌入式)
队列我们采用链表实现:顺序表在满了要扩容,删完了后再入队列的时候还得扩容
链表的话,入队列就是尾插,定义一个尾指针。出队列就是头删,定义一个头指针
- typedef int QDateType;
- typedef struct QueueNode
- {
- struct QueueNode* next;
- QDateType val;
- }QueueNode;
-
- typedef struct Queue
- {
- QueueNode* head;
- QueueNode* tail;
- }Queue;
这里的链表队列我并没有带头,没有带头就要在入队列和出队列时有一点特殊情况的考虑
- void QueueInit(Queue* ps)
- {
- assert(ps);
- ps->head = ps->tail = NULL;
- }
相当于尾插,考虑特殊情况:队列为空的情况
- //入队列:尾插
- void QueuePush(Queue* ps,QDateType x)
- {
- assert(ps);
- QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
- newnode->next = NULL;
- newnode->val = x;
- if (newnode == NULL)
- {
- perror("malloc fail.");
- exit(-1);
- }
- if (ps->tail == NULL)
- {
- ps->head = ps->tail = newnode;
- }
- else
- {
- ps->tail->next = newnode;
- ps->tail = ps->tail->next;
- }
- }
相当于头删,考虑特殊情况:只有一个结点的情况,出队列后要改变ps->tail
- void QueuePop(Queue* ps)
- {
- assert(ps);
- assert(!QueueEmpty(ps));
- if (ps->head->next == NULL)
- {
- free(ps->head);
- ps->head = ps->tail = NULL;
- }
- else
- {
- QueueNode* next = ps->head->next;
- free(ps->head);
- ps->head = next;
-
- }
- }
- QDateType QueueFront(Queue* ps)
- {
- assert(ps);
- assert(!QueueEmpty(ps));
- return ps->head->val;
- }
- QDateType QueueBack(Queue* ps)
- {
- assert(ps);
- assert(!QueueEmpty(ps));
- return ps->tail->val;
- }
- bool QueueEmpty(Queue* ps)
- {
- assert(ps);
- return ps->tail == NULL;
- }
- int QueueSize(Queue* ps)
- {
- assert(ps);
- int size = 0;
- QueueNode* cur = ps->head;
- while(cur)
- {
- ++size;
- cur = cur->next;
- }
- return size;
- }
- void QueueDestory(Queue* ps)
- {
- assert(ps);
- QueueNode* cur = ps->head;
- while (cur)
- {
- QueueNode* next = cur->next;
- free(cur);
- cur = next;
- }
- ps->head = ps->tail = NULL;
- }
- #define _CRT_SECURE_NO_WARNINGS 1
- #include"queue.h"
-
- void QueueInit(Queue* ps)
- {
- assert(ps);
- ps->head = ps->tail = NULL;
- }
-
- void QueueDestory(Queue* ps)
- {
- assert(ps);
- QueueNode* cur = ps->head;
- while (cur)
- {
- QueueNode* next = cur->next;
- free(cur);
- cur = next;
- }
- ps->head = ps->tail = NULL;
- }
-
- //入队列:尾插
- void QueuePush(Queue* ps,QDateType x)
- {
- assert(ps);
- QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
- newnode->next = NULL;
- newnode->val = x;
- if (newnode == NULL)
- {
- perror("malloc fail.");
- exit(-1);
- }
- if (ps->tail == NULL)
- {
- ps->head = ps->tail = newnode;
- }
- else
- {
- ps->tail->next = newnode;
- ps->tail = ps->tail->next;
- }
- }
-
- void QueuePop(Queue* ps)
- {
- assert(ps);
- assert(!QueueEmpty(ps));
- if (ps->head == ps->tail)
- {
- free(ps->head);
- ps->head = ps->tail = NULL;
- }
- else
- {
- QueueNode* next = ps->head->next;
- free(ps->head);
- ps->head = next;
-
- }
- }
-
- QDateType QueueFront(Queue* ps)
- {
- assert(ps);
- assert(!QueueEmpty(ps));
- return ps->head->val;
- }
-
- QDateType QueueBack(Queue* ps)
- {
- assert(ps);
- assert(!QueueEmpty(ps));
- return ps->tail->val;
- }
-
- bool QueueEmpty(Queue* ps)
- {
- assert(ps);
- return ps->tail == NULL;
- }
-
- int QueueSize(Queue* ps)
- {
- assert(ps);
- int size = 0;
- QueueNode* cur = ps->head;
- while(cur)
- {
- ++size;
- cur = cur->next;
- }
- return size;
- }
- #define _CRT_SECURE_NO_WARNINGS 1
-
- #include
- #include
- #include
- #include
-
- typedef int QDateType;
- typedef struct QueueNode
- {
- struct QueueNode* next;
- QDateType val;
- }QueueNode;
-
- typedef struct Queue
- {
- QueueNode* head;
- QueueNode* tail;
- }Queue;
-
- void QueueInit(Queue* ps);
-
- void QueuePush(Queue* ps, QDateType x);
-
- void QueuePop(Queue* ps);
-
- QDateType QueueFront(Queue* ps);
-
- QDateType QueueBack(Queue* ps);
-
- bool QueueEmpty(Queue* ps);
-
- int QueueSize(Queue* ps);
-
- void QueueDestory(Queue* ps);
- #define _CRT_SECURE_NO_WARNINGS 1
- #include"queue.h"
-
-
- int main()
- {
- Queue Q;
- QueueInit(&Q);
- QueuePush(&Q, 1);
- QueuePush(&Q, 2);
- QueuePush(&Q, 3);
- QueuePush(&Q, 4);
- QueuePush(&Q, 5);
- QDateType ret1 = QueueFront(&Q);
- printf("QueueFront:%d\n", ret1);
- QDateType ret2 = QueueBack(&Q);
- printf("QueueBack:%d\n", ret2);
- int size = QueueSize(&Q);
- printf("size:%d\n", size);
- while (!QueueEmpty(&Q))
- {
- printf("%d", QueueFront(&Q));
- QueuePop(&Q);
- }
- QueueDestory(&Q);
- return 0;
- }
制作不易,敬请三连