文章目录一研为定
- 第五次 直播 双向链表
- 双向链表的增删改查
- 双向链表的删除
- 第五次 直播 其他链表
- 循环单链表
- 静态链表
- 常见问题
- 第六次 直播 引用解析、栈与队列
- 栈的实现
- 栈的基本 *** 作
- 队列
- 循环队列
核心; 注意双向链表的插入次序 ①②③④ 标识
注意:赋值语句的解读 eg: p->next = s ; 的意思为将 s 的值赋给 p->next
双向链表的增删改查#include双向链表的删除#include typedef int ElemType; typedef struct DNode{ ElemType data; struct DNode *prior,*next;//前驱,后继 }DNode,*DlinkList; //双向链表头插法 DlinkList Dlist_head_insert(DlinkList &DL) { DNode *s;int x; DL=(DlinkList)malloc(sizeof(DNode));//带头结点的链表,不带头结点 DL->next=NULL; DL->prior=NULL; scanf("%d",&x);//从标准输入读取数据 //3 4 5 6 7 9999 while(x!=9999){ s=(DlinkList)malloc(sizeof(DNode));//申请一个空间空间,强制类型转换 s->data=x; s->next=DL->next; if(DL->next!=NULL)//插入第一个结点时,不需要这一步 *** 作 { DL->next->prior=s; } s->prior=DL; DL->next=s; scanf("%d",&x);//读取标准输入 } return DL; } //双向链表尾插法 DlinkList Dlist_tail_insert(DlinkList &DL) { int x; DL=(DlinkList)malloc(sizeof(DNode));//带头节点的链表 DNode *s,*r=DL; DL->prior=NULL; //3 4 5 6 7 9999 scanf("%d",&x); while(x!=9999){ s=(DNode*)malloc(sizeof(DNode)); s->data=x; r->next=s; s->prior=r; r=s;//r指向新的表尾结点 scanf("%d",&x); } r->next=NULL;//尾结点的next指针赋值为NULL return DL; } //按序号查找结点值 DNode *GetElem(DlinkList DL,int i) { int j=1; DNode *p=DL->next; if(i==0) return DL; if(i<1) return NULL; while(p&&jnext; j++; } return p; } //新结点插入第i个位置 bool DListFrontInsert(DlinkList DL,int i,ElemType e) { DlinkList p=GetElem(DL,i-1); if(NULL==p) { return false; } DlinkList s=(DlinkList)malloc(sizeof(DNode));//为新插入的结点申请空间 s->data=e; s->next=p->next; p->next->prior=s; s->prior=p; p->next=s; return true; } //删除第i个结点 bool DListDelete(DlinkList DL,int i) { DlinkList p=GetElem(DL,i-1); if(NULL==p) { return false; } DlinkList q; q=p->next; if(q==NULL)//删除的元素不存在 return false; p->next=q->next;//断链 // 下面注意要进行判断 if(q->next!=NULL) { q->next->prior=p; } free(q);//释放对应结点的空间 return true; } //链表打印 void PrintDList(DlinkList DL) { DL=DL->next; while(DL!=NULL) { printf("%3d",DL->data); DL=DL->next; } printf("n"); } //2.3.3 双链表增删查 int main() { DlinkList DL; DlinkList search; Dlist_head_insert(DL); //Dlist_tail_insert(DL); //3 4 5 6 7 9999 PrintDList(DL); search=GetElem(DL,2); if(search!=NULL) { printf("按序号查找成功n"); printf("%dn",search->data); } DListFrontInsert(DL,3,99); PrintDList(DL); DListDelete(DL,2); PrintDList(DL); system("pause"); }
= 删除双链表中结点*p的后继结点*q
1、p->next=q->next ;
2、q->next-> prior=p;
3、free(q) ;
- 循环单链表与单链表的区别在于,表中最后一个结点的next指针不是NULL,而是指向头结点L,从而整个链表形成一个环
- 静态链表是借助数组来描述线性表的链式存储结构,结构类型如下
#define Maxsize 50 typedef struct { ElemType data ; int next ; ) Slinklist[Maxsize] ;常见问题
- 在链表中插入第 i 个位置和删除第 i 个元素不需要用引用的原因在于:不需要改变头节点
为什么我们需要在形参的地方使用引用?
- 在子函数中去给对应的形参赋值后,子函数结束,主函数中对应的实参就发生了变化,如果没有使用引用,那么在子函数中给形参赋值后,子函数结束,主函数中对应的实参不会变化的
- 入栈:Top 栈顶指针先加加 ; 出栈:Top 栈顶指针后减减
#include#include #define MaxSize 50 typedef int ElemType; typedef struct { ElemType data[MaxSize];//数组 int top; }SqStack; void InitStack(SqStack &S) { S.top = -1;//代表栈为空 } bool StackEmpty(SqStack S) { if (-1 == S.top) { return true; } return false; } bool Push(SqStack& S, ElemType x) { if (S.top == MaxSize - 1) { return false;//栈满了 } S.data[++S.top] = x; return true;//返回true就是入栈成功 } //获取栈顶元素 bool GetTop(SqStack S, ElemType &x) { if (StackEmpty(S))//栈为空 { return false; } x = S.data[S.top]; return true; } bool Pop(SqStack& S, ElemType& x) { if (StackEmpty(S))//栈为空 { return false; } x = S.data[S.top--];//等价于x = S.data[S.top];再做 S.top--; return true; } int main() { SqStack S; bool flag; ElemType m;//存储拿出来的栈顶元素的 InitStack(S);//初始化 flag = StackEmpty(S); if (flag) { printf("栈是空的n"); } Push(S, 3);//入栈元素3 Push(S, 4);//入栈元素4 Push(S, 5); flag = GetTop(S, m);//获取栈顶元素,但是S.top值不变 if (flag) { printf("获取栈顶元素为 %dn", m); } flag = Pop(S, m);//d出栈顶元素 if (flag) { printf("d出元素为 %dn", m); } return 0; }
拓展知识: 链表实现的栈是头部插入与头部删除
循环队列图示
为了区分队空还是队满的情况:
1、以牺牲一个单元区分队空和队满
2、类型中增设表示数据元素个数的数据单元
3、类型中增设tag 数据成员
入队
出队
队列全局代码
#include#include #define MaxSize 5 typedef int ElemType; typedef struct{ ElemType data[MaxSize];//数组,存储MaxSize-1个元素 int front,rear;//队列头 队列尾 }SqQueue; void InitQueue(SqQueue &Q) { Q.rear=Q.front=0; } //判空 bool isEmpty(SqQueue &Q) { if(Q.rear==Q.front)//不需要为零 return true; else return false; } //入队 bool EnQueue(SqQueue &Q,ElemType x) { if((Q.rear+1)%MaxSize==Q.front) //判断是否队满 return false; Q.data[Q.rear]=x;//3 4 5 6 Q.rear=(Q.rear+1)%MaxSize; return true; } //出队 bool DeQueue(SqQueue &Q,ElemType &x) { if(Q.rear==Q.front) return false; x=Q.data[Q.front];//先进先出 Q.front=(Q.front+1)%MaxSize; return true; } //《王道C督学营》课程 //王道数据结构 3.2 循环队列 int main() { SqQueue Q; bool ret;//存储返回值 ElemType element;//存储出队元素 InitQueue(Q); ret=isEmpty(Q); if(ret) { printf("队列为空n"); }else{ printf("队列不为空n"); } EnQueue(Q,3); EnQueue(Q,4); EnQueue(Q,5); ret=EnQueue(Q,6); ret=EnQueue(Q,7); if(ret) { printf("入队成功n"); }else{ printf("入队失败n"); } ret=DeQueue(Q,element); if(ret) { printf("出队成功,元素值为 %dn",element); }else{ printf("出队失败n"); } ret=DeQueue(Q,element); if(ret) { printf("出队成功,元素值为 %dn",element); }else{ printf("出队失败n"); } ret=EnQueue(Q,8); if(ret) { printf("入队成功n"); }else{ printf("入队失败n"); } system("pause"); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)