目录
后记:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!
详细实现链接:
<栈(动态版)>《数据结构(C语言版)》
<队列(链式)>《数据结构(C语言版)》
1.1栈的实现结构方式:
数组实现栈的结构:
相当于顺序表的尾插、尾删,用尾作栈顶,非常合适!从CPU预加载命中角度分析,数组实现的性能更好一些!
缺点:空间不够时需要增容。
单向链表实现栈的结构:
用头结点作栈底,这样使得入栈和出栈效率都是O(1)。
双向链表实现栈的结构:
用尾作栈顶。
1.2 队列的实现方式:
数组实现队列的结构:
不适合,队头出数据需要挪动数据
单链表实现队列的结构:
无需使用带头结点的单链表即可完成,带头结点是为了减少二级指针的使用。
tail是移动的,方便尾部操作直接找到。head方便头部操作直接找到。
数据结构的设计比较灵活,正所谓:“树挪死,人挪活”。在学习中,不要一味地“守死”,而要学会“变活。”
2.1栈的模拟实现:
Stack.h:
#pragma once #include #include #include #include typedef char STDataType; typedef struct Stack { STDataType* a; //通过数组实现栈的结构 int top; int capacity; }ST; //初始化 void StackInit(ST* ps); //释放内存、销毁空间 void StackDestory(ST* ps); // 入栈 void StackPush(ST* ps, STDataType x); // 出栈 void StackPop(ST* ps); //取栈顶数据 STDataType StackTop(ST* ps); //栈的大小 int StackSize(ST* ps); //判空 bool StackEmpty(ST* ps);Stack.c:
#include"Stack.h" //初始化 void StackInit(ST* ps) { assert(ps); ps->a = (STDataType*)malloc(sizeof(STDataType) * 4); if (ps->a == NULL) { printf("malloc fail!\n"); exit(-1); } ps->capacity = 4; ps->top = 0; //这使得top最终指向的是栈顶的后一个位置。若top=-1,则最终指向的是栈顶。 } //释放内存、销毁空间 void StackDestory(ST* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->top = ps->capacity = 0; } // 入栈 void StackPush(ST* ps, STDataType x) { assert(ps); // 满了->增容 if (ps->top == ps->capacity) { STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType)); if (tmp == NULL) { printf("realloc fail!\n"); exit(-1); } else { ps->a = tmp; ps->capacity *= 2; } } ps->a[ps->top] = x; ps->top++; } // 出栈 void StackPop(ST* ps) { assert(ps); // 栈空了,再调用Pop,就会直接中止程序报错 assert(ps->top > 0); //ps->a[ps->top - 1] = 0; //置为0只考虑了int型等,若为char、double等就不适用了。 ps->top--; } //取栈顶数据 STDataType StackTop(ST* ps) { assert(ps); // 栈空了,再调用Top,就会直接中止程序报错 assert(ps->top > 0); return ps->a[ps->top - 1]; } //求栈大小 int StackSize(ST* ps) { assert(ps); return ps->top; } //判空 bool StackEmpty(ST* ps) { assert(ps); return ps->top == 0; } //判断括号是否匹配算法 bool isValid(char* s) { ST st; StackInit(&st); while (*s != '\0') { switch (*s) { case '{': case '[': case '(': { StackPush(&st, *s); ++s; break; } case '}': case ']': case ')': { if (StackEmpty(&st)) { StackDestory(&st); return false; } char top = StackTop(&st); StackPop(&st); // 不匹配 if ((*s == '}' && top != '{') || (*s == ']' && top != '[') || (*s == ')' && top != '(')) { StackDestory(&st); return false; } else // 匹配 { ++s; } break; } default: break; } } bool ret = StackEmpty(&st); StackDestory(&st); return ret; }Test.c:
#include"Stack.h" int main() { ST st; StackInit(&st); StackPush(&st, 9); StackPush(&st, 5); StackPush(&st, 2); StackPush(&st, 7); printf("%d \n", StackEmpty(&st)); printf("%d \n", StackSize(&st)); while (!StackEmpty(&st)) { printf("%d ", StackTop(&st)); StackPop(&st); } printf("\n"); StackDestory(&st); return 0; }2.2 队列的模拟实现:
Queue.h:
#pragma once #include #include #include #include typedef int QDataType; typedef struct QueueNode { struct QueueNode* next; QDataType data; }QNode; typedef struct Queue { QNode* head; QNode* tail; }Queue; //初始化 void QueueInit(Queue* pq); //销毁 void QueueDestory(Queue* pq); // 队尾入 void QueuePush(Queue* pq, QDataType x); // 队头出 void QueuePop(Queue* pq); //取队列头元素 QDataType QueueFront(Queue* pq); //取队列尾元素 QDataType QueueBack(Queue* pq); //队列大小 int QueueSize(Queue* pq); //队列判空 bool QueueEmpty(Queue* pq);Queue.c:
#include"Queue.h" //初始化 void QueueInit(Queue* pq) { assert(pq); pq->head = pq->tail = NULL; } //销毁 void QueueDestory(Queue* pq) { assert(pq); QNode* cur = pq->head; while (cur) { QNode* next = cur->next; free(cur); cur = next; } pq->head = pq->tail = NULL; } // 队尾入 void QueuePush(Queue* pq, QDataType x) { assert(pq); QNode* newnode = (QNode*)malloc(sizeof(QNode)); if (newnode == NULL) { printf("malloc fail!\n"); exit(-1); } newnode->data = x; newnode->next = NULL; if (pq->tail == NULL) { pq->head = pq->tail = newnode; } else { pq->tail->next = newnode; pq->tail = newnode; } } // 队头出 void QueuePop(Queue* pq) { assert(pq); assert(pq->head); // 1、一个 // 2、多个 if (pq->head->next == NULL) { free(pq->head); pq->head = pq->tail = NULL; } else { QNode* next = pq->head->next; free(pq->head); pq->head = next; } } //取队头元素 QDataType QueueFront(Queue* pq) { assert(pq); assert(pq->head); return pq->head->data; } //取队尾元素 QDataType QueueBack(Queue* pq) { assert(pq); assert(pq->head); return pq->tail->data; } //队列大小 int QueueSize(Queue* pq) { assert(pq); int size = 0; QNode* cur = pq->head; while (cur) { ++size; cur = cur->next; } return size; } //队列判空 bool QueueEmpty(Queue* pq) { assert(pq); return pq->head == NULL; }Test.c:
#include"Queue.h" void TestQueue() { Queue q; QueueInit(&q); QueuePush(&q, 1); QueuePush(&q, 2); printf("%d ", QueueFront(&q)); QueuePop(&q); printf("%d ", QueueFront(&q)); QueuePop(&q); QueuePush(&q, 3); QueuePush(&q, 4); while (!QueueEmpty(&q)) { printf("%d ", QueueFront(&q)); QueuePop(&q); } printf("\n"); QueueDestory(&q); } int main() { TestQueue(); return 0; }3.判断括号匹配程序:
#include #include #include #include /// //声明 typedef char STDataType; typedef struct Stack { STDataType* a; int top; int capacity; }ST; // //定义 //初始化 void StackInit(ST* ps) { assert(ps); ps->a = (STDataType*)malloc(sizeof(STDataType) * 4); if (ps->a == NULL) { printf("malloc fail\n"); exit(-1); } ps->capacity = 4; ps->top = 0; } //销毁 void StackDestory(ST* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->top = ps->capacity = 0; } // 入栈 void StackPush(ST* ps, STDataType x) { assert(ps); // 满了-》增容 if (ps->top == ps->capacity) { STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType)); if (tmp == NULL) { printf("realloc fail\n"); exit(-1); } else { ps->a = tmp; ps->capacity *= 2; } } ps->a[ps->top] = x; ps->top++; } // 出栈 void StackPop(ST* ps) { assert(ps); // 栈空了,调用Pop,直接中止程序报错 assert(ps->top > 0); //ps->a[ps->top - 1] = 0; ps->top--; } //去栈顶元素 STDataType StackTop(ST* ps) { assert(ps); // 栈空了,调用Top,直接中止程序报错 assert(ps->top > 0); return ps->a[ps->top - 1]; } //求栈的的大小 int StackSize(ST* ps) { assert(ps); return ps->top; } //判空 bool StackEmpty(ST* ps) { assert(ps); return ps->top == 0; } //判断括号是否匹配 bool isValid(char* s) { ST st; StackInit(&st); while (*s != '\0') { switch (*s) { case '{': case '[': case '(': { StackPush(&st, *s); ++s; break; } case '}': case ']': case ')': { if (StackEmpty(&st)) { StackDestory(&st); return false; } char top = StackTop(&st); StackPop(&st); // 不匹配 if ((*s == '}' && top != '{') || (*s == ']' && top != '[') || (*s == ')' && top != '(')) { StackDestory(&st); return false; } else // 匹配 { ++s; } break; } default: break; } } bool ret = StackEmpty(&st); StackDestory(&st); return ret; } int main() { //int ret = isValid("[[["); //int ret = isValid("[]["); int ret = isValid("[]"); if (ret == 0) { printf("不匹配!\n" ); } else { printf("匹配!\n"); } return 0; }