02 stack queue linked-list¶
统计信息:字数 8586 阅读18分钟
第2章 栈、队列、链表¶
第1节 解密QQ号——队列:queue,FIFO 先进先出。结构体由一个数组,开始的指针,结束的指针组成。支持增加和减少。减少时,头指针加一;增加时,尾指针增加一,前一个的值是新的值。
第2节 解密回文——栈:stack 只需要存储一个数组和一个顶点指针。FILO 先进后出,操作顶部指针即可。
第3节 纸牌游戏——小猫钓鱼:队列和栈的综合应用
第4节 链表:C语言中通过指针实现链表(需要一部分深入C语言语法)
指针用途:存储一个地址
&:取地址符号(获取指针的地址)
*:三个用途(乘号;声明指针变量(int *q); 间接访问运算符(printf("%d", *p)))
malloc: 从内存中申请分配指定字节的大小的内存空间, p = (int *)malloc(sizeof(int))
malloc 函数返回的是 void * 类型,可以强制转换成其他类型的指针
指针变量存储的是一个内存地址的首地址,但是这个空间占用多少字节,存储什么数据类型,需要由指针的数据类型标明
-> 叫做结构体指针运算符(因为指针指向结构体,不能使用 . 访问内部成员,只能使用 -> 访问)
第5节 模拟链表:使用两个数组模拟链表和指针(数据数组和指针数组实现)
01-queue
#include <stdio.h>
int main() {
int q[102] = {0, 6, 3, 1, 7, 5, 8, 9, 2, 4};
int head, tail;
head = 1;
// queue 中有9个值,所以尾指针指向10
tail = 10;
while (head < tail) {
// 删除奇数元素
printf("%d", q[head]);
head++;
// 把偶数元素移动到尾部
q[tail] = q[head];
tail++;
head++;
}
getchar();
getchar();
return 0;
}
02-queue-struct
#include <stdio.h>
struct queue {
int data[100];
int head;
int tail;
};
int main() {
struct queue q;
int i;
q.head = 1;
q.tail = 1;
// init queue
for (i = 1; i <= 9; i++) {
scanf("%d", &q.data[q.tail]);
q.tail++;
}
// move and delete number
while (q.head < q.tail) {
printf("%d", q.data[q.head]);
q.head++;
q.data[q.tail] = q.data[q.head];
q.head++;
q.tail++;
}
getchar();
getchar();
return 0;
}
03-stack.c
#include <stdio.h>
#include <string.h>
int main() {
char a[101], s[101];
int i, len, mid, next, top;
gets(a); // 读入一行字符串
len = strlen(a);
mid = len / 2 - 1;
top = 0;
for (i = 0; i < mid; i++) {
s[top] = a[i];
top++;
}
if (len % 2 == 0) {
next = mid + 1;
}
else {
next = mid + 2;
}
for (i = next; i < len - 1; i++) {
if (a[i] != s[top]) {
break;
}
top--;
}
char x = 't';
char y = 'f';
if (top == 0) {
printf("%c", x);
}
else {
printf("%c", y);
}
return 0;
}
04-cat-and-fish
#include <stdio.h>
struct queue {
int data[100];
int head;
int tail;
};
struct stack {
int data[10];
int top;
};
int main() {
struct queue q1, q2;
struct stack s;
int book[10];
int i, t;
// init queue
q1.head = 1;
q1.tail = 1;
q2.head = 1;
q2.tail = 1;
// init stack
s.top = 0;
// init array (cards in desk) no card i is 0, has card i is 1
for (i = 0; i < 10; i++) {
book[i] = 0;
}
// each user has 6 cards
for (i = 1; i <= 6; i++) {
scanf("%d", &q1.data[q1.tail]);
q1.tail++;
scanf("%d", &q2.data[q2.tail]);
q2.tail++;
}
while (q1.head < q1.tail && q2.head < q2.tail) {
t = q1.data[q1.head];
// check if there is a card is equal with q1 head
if (book[t] == 0) {
q1.head++;
s.top++;
s.data[s.top] = t;
book[t] = 1;
}
// 如果桌面上已经有这张牌
else {
// 先把打出的这张牌收回到末尾
q1.head++;
q1.data[q1.tail] = t;
q1.tail++;
// 然后遍历桌面上的纸牌,放到队列尾部,并取消标记
while (s.data[s.top] != t) {
book[s.data[s.top]] = 0;
q1.data[q1.tail] = s.data[s.top];
q1.tail++;
s.top--;
}
// 收回桌面上牌面为t的牌
book[s.data[s.top]] = 0;
q1.data[q1.tail] = s.data[s.top];
q1.tail++;
s.top--;
}
// 如果开始等于结束,证明手中无牌,结束
if (q1.head == q1.tail) {
break;
}
// 另一个人
t = q2.data[q2.head];
// check if there is a card is equal with q2 head
if (book[t] == 0) {
q2.head++;
s.top++;
s.data[s.top] = t;
book[t] = 1;
}
// 如果桌面上已经有这张牌
else {
// 先把打出的这张牌收回到末尾
q2.head++;
q2.data[q2.tail] = t;
q2.tail++;
// 然后遍历桌面上的纸牌,放到队列尾部,并取消标记
while (s.data[s.top] != t) {
book[s.data[s.top]] = 0;
q2.data[q2.tail] = s.data[s.top];
q2.tail++;
s.top--;
}
// 收回桌面上牌面为t的牌
book[s.data[s.top]] = 0;
q2.data[q2.tail] = s.data[s.top];
q2.tail++;
s.top--;
}
}
// 结束游戏判断
if (q2.head == q2.tail) {
for (i = q1.head; i < q1.tail; i++) {
printf("%d", q1.data[i]);
}
if (s.top > 0) {
for (i = 0; i < s.top; i++) {
printf("%d", s.data[i]);
}
}
else {
printf("There is no card in dest");
}
}
else {
for (i = q2.head; i < q2.tail; i++) {
printf("%d", q2.data[i]);
}
if (s.top > 0) {
for (i = 0; i < s.top; i++) {
printf("%d", s.data[i]);
}
}
else {
printf("There is no card in dest");
}
}
getchar();
getchar();
return 0;
}
05-linked-list
#include <stdio.h>
#include <stdlib.h>
// 辅助函数:指针基本知识
int pointer_foo() {
int a = 10;
int *p;
// 指针B指向A,那么通过指针B即可访问变量A的值
p = &a;
printf("%d", *p);
return 0;
}
// 辅助函数:动态开辟指针内存
int malloc_foo() {
int *p;
// 设置指针获取动态分配的内存地址
p = (int *)malloc(sizeof(int));
// 指针所存储的内存空间中存10
*p = 10;
printf("%d", *p);
return 0;
}
// 结构体表示链表的节点类型
struct node {
int data;
// 声明一个指针,指向下一个 node 节点的指针
struct node *next;
};
// 主函数
int main() {
struct node *head, *p, *q, *t;
int i, n, a;
scanf("%d", &n);
// 设置头指针初始为空
head = NULL;
for (i = 1; i <= n; i++) {
scanf("%d", &a);
// 动态申请临时节点
p = (struct node *)malloc(sizeof(struct node));
p -> data = a;
p -> next = NULL;
// 如果链表是空,那么就把头指针指向这个节点
if (head == NULL) {
head = p;
}
// 如果不是空链表,那么把前一个节点(q)的指针,指向当前节点(p)
// 然后把当前节点变成前一个节点(q)
else {
q -> next = p;
q = p;
}
}
// 读入输入的数字(新加入的数字,放在临时变量a中)
scanf("%d", &a);
// 遍历链表,找到合适的插入位置
t = head;
while (t != NULL) {
// 如果遍历到结尾,或者某个节点的值大于a
// 那么把A节点插入其中(改变指针的指向)
if (t -> next == NULL || t -> next -> data > a) {
p = (struct node *)malloc(sizeof(struct node));
p -> data = a;
p -> next = t -> next;
t -> next = p;
break;
}
t = t -> next;
}
// 打印插入后的链表
t = head;
while (t != NULL) {
printf("%d", t -> data);
t = t -> next;
}
getchar();
getchar();
return 0;
}
06-linked-list-array
#include <stdio.h>
// use two array to generate linked list
int main() {
int data[101], right[101];
int i, n, t, len;
// init data array
scanf("%d", &n);
for (i = 1; i <= n; i++) {
scanf("%d", &data[i]);
}
len = n;
// init right pointer array
for (i = 1; i <= n; i++) {
if (i != n) {
right[i] = i + 1;
}
else {
right[i] = 0;
}
}
// 直接把新加入的数组,放在数据数组的最后一位
len++;
scanf("%d", &data[len]);
// 然后改变指针数组
t = 1;
while (t != 0) {
if (data[right[t]] > data[len]) {
right[len] = right[t];
right[t] = len;
break;
}
t = right[t];
}
// print linked list
t = 1;
while (t != 0) {
printf("%d", data[t]);
t = right[t];
}
getchar();
return 0;
}
Last update:
November 9, 2024