关于数据结构栈和链表

mac2026-06-12  14

关于数据结构栈和链表

基础任务一:实现一个数据结构栈,完成Init()、push()、pop()、getTop()等栈的基本函数。

我觉得栈相当于“先进后出”的一个数据结构,先放进去的数据后用,后放进去的数据先用,就大概一个有很多个格子的箱子,有节点。我们用“push"压栈,用”pop"出栈,用top变量记录栈顶的位置。实现方式分为数组实现和链表实现。

/**栈的初始化*/ void init(PSTACK); /**压栈*/ void push(PSTACK,int); /**出栈*/ int pop(PSTACK , int *); /**遍历打印栈*/ void traverse(PSTACK); /**是否为空栈*/ int isEmpty(PSTACK); /**清空栈*/ void clearStack(PSTACK);

感受:我会觉得栈比数组要方便很多,因为数组要考虑下标,考虑不能直接引用数组,而要用a[1]这样的,也要考虑对一个空数组赋值,用for循环一个一个去填,在输出的时候,也不能说直接打印整个数组,但是呢,栈就很方便啊,不仅可以按一定顺序存,逆序用,还可以用指针指向某个元素或者节点,提高效率吧。

基础任务二:实现一个数据结构队列,完成Init()、EnQueue()、DeQueue()、getFront()等队列的基本函数。

首先先去学习关于队列的相关知识:队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。同样地它也有数组实现和链表实现两种方式。但是呢,简单数组实现中由于front之前的空间不能再次使用,就会出现,后面的元素输不进去,前面的空间又被浪费的局面,所以,可以试试循环数组? 末尾元素的下一位又是首元素,就可以利用了。BUT,怎么判断是空还是满呢,毕竟例如rear和front相邻时就无法辨别空还是满。

//入队功能函数 调用EnQueue函数 void EnterToQueue(SqQueue &Q) { int n; QElemType e; int flag; printf("请输入入队元素个数(>=1):\n"); scanf("%d",&n); for(int i=0;i<n;i++) { printf("请输入第%d个元素的值:",i+1); scanf("%d",&e); flag=EnQueue(Q,e); if(flag) printf("%d已入队\n",e); else { printf("队已满!!!\n");break; } } } //出队函数 调用DeQueue函数 void DeleteFromQueue(SqQueue &Q) { int n; QElemType e; int flag; printf("请输入出队元素个数(>=1):\n"); scanf("%d",&n); for(int i=0;i<n;i++) { flag=DeQueue(Q,e); if(flag) printf("%d已出队\n",e); else { printf("队已空!!!\n");break; } } } //获得队头元素 调用GetHead函数 void GetHeadOfQueue(SqQueue Q) { QElemType e;bool flag; flag=GetHead(Q,e); if(flag)printf("队头元素为:%d\n",e); else printf("队已空!!!\n"); }

基础任务三:继续学习单向/双向/循环链表的基本操作。

Q1

栈的应用 1.LeetCode题号:20. 有效的括号(简单)给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。注意空字符串可被认为是有效字符串。

# include <stdio.h> # include <stdlib.h> # include <alloc.h> bool isValid(char * s){ if (s == NULL || s[0] == '\0') return true; char *stack = (char*)malloc(strlen(s)+1); int top =0; for (int i = 0; s[i]; ++i) { if (s[i] == '(' || s[i] == '[' || s[i] == '{') stack[top++] = s[i]; else { if ((--top) < 0) return false;//先减减,让top指向栈顶元素 if (s[i] == ')' && stack[top] != '(') return false; if (s[i] == ']' && stack[top] != '[') return false; if (s[i] == '}' && stack[top] != '{') return false; } } return (!top);//防止“【”这种类似情况 }

Q2

LeetCode题号: 150. 逆波兰表达式求值(中等)根据逆波兰表示法,求表达式的值。有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。说明:整数除法只保留整数部分。给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

int evalRPN(char ** tokens, int tokensSize) { int stack[16384], top = 0; int num1, num2; for(int i = 0; i < tokensSize; i++){ if(tokens[i][1] == '\0' && (tokens[i][0] == '+' || tokens[i][0] == '-' || tokens[i][0] == '*' || tokens[i][0] == '/')){ num2 = stack[--top]; num1 = stack[--top]; switch(tokens[i][0]) { case '-' : stack[top++] = num1 - num2; break; case '+' : stack[top++] = num1 + num2; break; case '*' : stack[top++] = num1 * num2; break; case '/' : stack[top++] = num1 / num2; break; default : break; } }else{ stack[top++] = atoi(tokens[i]); } } return stack[--top]; }

Q3

链表的应用1.LeetCode题号: 21. 合并两个有序链表(简单)将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){ if(l1 == NULL) return l2; if(l2 == NULL) return l1; struct ListNode newhead, *p1, *p2; newhead.next = l1; l1 = &newhead; while(l2 != NULL) { p1 = l1->next; p2 = l2->next; if(p1 == NULL) { l1->next = l2; break; } if(l2->val <= p1->val) { l2->next = l1->next; l1->next = l2; l2 = p2; } l1 = l1->next; } return newhead.next; }

Q4

LeetCode题号: 2. 两数相加(中等)给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

int c=0; struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){ if(l1==NULL&&l2==NULL&&c==0)return NULL; l1!=NULL?(c+=l1->val,l1=l1->next):(c+=0); l2!=NULL?(c+=l2->val,l2=l2->next):(c+=0); struct ListNode *cur=(struct ListNode *)malloc(sizeof(struct ListNode)); cur->val=c%10; c=c/10; cur->next=addTwoNumbers(l1,l2); return cur; }

我总结一下,以上各题凡是看起来不像我水平的全部来自leetcode题解中各位大神,我真的觉得我学得慢而且上手也慢,目前我还在指针的应用中挣扎,看了一点链表,栈和数据结果列看了一大部分。

最新回复(0)