目录
一、开源项目推荐
二、线性表的基本运算在单链表上的实现
(1)初始化
(2)插入 p 指向的新结点的操作
(3)删除 *p 节点
三、循环链表
(1)在单链表中
(2)在带有头结点的循环链表中
(3)只有尾指针 rear
四、双向循环链表
(1)每个结点有两个指针
(2)带头结点的双向循环链表 L 为空的条件
(3)p 指向待删结点,删除 *p 的操作
(4)p 所指结点的后面插入一个结点 *t 的操作
五、栈的顺序实现
(1)下溢 / 上溢
(2)进栈
(3)出栈
(4)取栈顶元素
六、栈的链接实现
七、二叉树的性质
八、二叉树遍历的递归实现
九、图的遍历
十、4 种排序方法
一、开源项目推荐
【我的项目】数据结构导论_伪代码练习题https://gitcode.com/qq_39720249/data_structure/overview【项目说明】
- 数据结构导论:自学考试笔试题中关于伪代码的练习题集合
二、线性表的基本运算在单链表上的实现
(1)初始化
① 假设单链表的类型定义如下
typedef struct node { DataType data; struct node *next; }node ,*LinkList;
算法 InitiateLinkList()实现单链表的初始化
LinkList InitiateLinkList( ) // 建立一个空的单链表 { LinkList head; // 头指针 head=malloc(sizeof(node)); // 动态构建一个结点,并定义为头结点 head->next=NULL; return head; } // 空表由一个头指针 head 和一个头结点组成。 // head 指向新创建的结点,即头结点。 // 一个空单链表仅有一个头结点,它的指针域为 NULL。
② 在带头结点的单链表 L 中,第一个数据元素结点的指针为 L->next。
③ 设有一个单链表,若结点的指针域为 next,则指针 p 所指的结点为最后一个结点的条件是 p->next==NULL。工作指针 p->next 为 NULL 时,说明已经走到了表的尾部,这时已完成对所有结点的访问。
(2)插入 p 指向的新结点的操作
① 设 r 指向单链表的最后一个结点,要在最一个结点之后插入 s 所指的结点,需执行的语句序列是:r->next=s;r=s;r->next=NULL② 将一个由指针 q 指向的结点插在单链表中由指针 p 所指向的结点之后的操作是:q->next=p->next;p->next=q;
(3)删除 *p 节点
在一个单链表中,已知指针 q 指向指针 p 所指结点的前驱结点,则删除 *p 结点的操作语句是:
q->next=p->next
三、循环链表
(1)在单链表中
在单链表中,如果让最后一个结点的指针域指向第一个结点可以构成循环链表:① 只有头指针 head:
- 判断 P 所指结点为尾结点的条件:p->next==head;
- 判断指针 P 所指结点为首结点的条件: p==rear->next->next;
- 判断链表是否为空的条件:head->next==head。
② 有头指针 head 和尾指针 rear(说明:rear->next 指向头结点 head)。
(2)在带有头结点的循环链表中
在带有头结点的循环链表中,尾指针为 rear,判断指针 P 所指结点为首结点的条件是:
p==rear->next->next
(3)只有尾指针 rear
① 删除表首结点的操作可表示为:p=rear->next->next;rear->next->next=p->next;free(p);② 已知尾指针的单向循环链表在第一个结点后面插入一个新结点的时间复杂度为 O(1)。
四、双向循环链表
(1)每个结点有两个指针
- next 指针指向直接后继结点
- prior 指针指向直接前驱结点
(2)带头结点的双向循环链表 L 为空的条件
(L->next==L)&&(L->prior==L)
(3)p 指向待删结点,删除 *p 的操作
p->prior->next=p->next;p->next->prior=p->prior;free(p);
(4)p 所指结点的后面插入一个结点 *t 的操作
t->prior=p;t->next=p->next;p->next->prior=t;p->next=t;
五、栈的顺序实现
(1)下溢 / 上溢
- 当空栈,栈顶下标值 top=0,如果此时做出栈运算,则产生“下溢”。
- 当栈中的数据元素已经填满了,如果再进行进桟操作,会发生“上溢”。
(2)进栈
Int Push(SeqStk *stk,DataType x) // 若栈未满,元素 x 进栈 stk 中,否则提示出错信息
{if(stk->top==maxsize-1) // 判断找是否满
{ error(“栈已满”);return 0;}
else { stk->top++; // 栈未满,top 值加 1
stk->data[stk->top]=x; // 元素 x 进桟
return 1;}}
(3)出栈
Int Pop{SeqStk *stk)
{ if(EmptyStack(stk)) // 判断是否下溢(栈空)
{ error(“下溢”);return 0;}
else // 未下溢,栈顶元素出栈
{ stk->top--; // top 值减 1
return 1;}}
也可以理解为:原栈顶的下一个结点成为新的栈顶,即 top=top->next;
(4)取栈顶元素
DataType GetTop(SeqStk*stk) // 取栈顶数据元素,栈顶数据元素逋过参数返回
{ if(EmptyStack(stk))
return NULLData; // 栈空,返回 NULLData
else return stk->data[stk->top];} // 返回栈顶数据元素
六、栈的链接实现
(1)栈的链接实现称为链栈,链栈可以用带头结点的单链表来实现。LS 指向链表的头结点,首结点是栈顶结点,LS->next 指向栈顶结点,尾结点为栈底结点。(2)出栈操作始终是栈顶结点出栈,即删除头结点之后的结点:原栈顶的下一个结点成为新的栈顶,即 top=top->next;(3)链栈由于采用了链表的方式作为存储方式,各结点通过链域的连接组成栈,由于每个结点空间都是动态分配产生,链栈不用预先考虑容量的大小。(4)入栈时,使用 malloc 申请空间后,用指针相连接,所以节点个数没有限制;但是出栈时,如果栈中的元素个数为 0,则不能继续出栈,所以需要判断当前栈是否为空。综上,链表不需要判满,只需要判定是否为空即可。(5)链栈 LS 中,Ls 一>next 指向栈顶结点,则新结点 *P 入栈的操作为:P->next=LS->next; 和 LS->next=p;。
七、二叉树的性质
八、二叉树遍历的递归实现
- 先序遍历:访问根结点;先序遍历左子树;先序遍历右子树。
- 中序遍历:中序遍历左子树;访问根结点;中序遍历右子树。
- 后序遍历:后序遍历左子树;后序遍历右子树;访问根结点。