文章目录
一、顺序表
1.链式存储的建表增删:
代码你有时间可以看一看,我给你写好了备注。
#include<stdio.h>
#include<string.h>
#define N 100
int ans=0; //标记作用
typedef struct
{
int elem[N]; //定义一个结构体,包含一个整形数组
int last; //记录线性表中最后一个元素下标的位置
} seqlist; //结构体名称
void inslist(seqlist *L,int i,int e)
{//inslist函数作用:在线性表L中,第i个位置前插入元素e
if(i<1||i>L->last+2||L->last>=N-1)//可插入的范围:1<=i<=L->last+2
{ //L->last>=N-1代表线性表存储超限,数据溢出
printf("插入错误!\n\n");
ans=1; //标记作用
return; //直接结束函数
}
for(int k=L->last; k>=i-1; k--)
L->elem[k+1]=L->elem[k];//为插入元素而移动位置
L->elem[i-1]=e; //第i-1项变成e
L->last++; //线性表最一为下标++
return;
}
void del(seqlist *L,int i)//del函数作用:删除线性表L中的第i个元素
{
if((i<1)||(i>L->last+1))//可删除范围:1<=i<<L->last+1
{
printf("删除错误!\n\n");
ans=1; //标记
return; //直接结束
}
for(int k=i; k<=L->last; k++)
L->elem[k-1]=L->elem[k]; //直接把元素前移
L->last--; //最后一位下表--
return;
}
void prin(seqlist *L) //pein函数作用:输出线性表L中的元素
{
for(int i=0; i<=L->last; i++)
printf("%d ",L->elem[i]); //指针结构体,所以用'->'
printf("\n\n");
}
int main()
{
char Q; //代表操作类型,Q=I 插入元素,Q=D:删除元素,Q=E:程序结束
int n,m,i,j,x,y; //m:m个数据
seqlist *L,test;//定义结构体变量test和指针结构体变量L
scanf("%d",&m);
for(i=0; i<m; i++) //把m个数据存入结构体数组中
scanf("%d",&test.elem[i]);
test.last=m-1; //记录最后一位元素
L=&test; //直接令L对test取地址
getchar();//由于下面需要数组字符变量,所以在此用getchar()吸收多余的回车字符
while(~scanf("%c",&Q)) //输入数据有多组'~'是控制格式
{
ans=0; //每次将标记归0
if(Q=='E')break;
if(Q=='D')
{
scanf("%d",&x);//删除第x个元素
del(L,x);//直接调用函数即可
if(ans) continue; //ans=1代表了数据范围不对,跳过本次循环进行下一次
printf("删除第%d个元素得:\n",x);
prin(L);
continue;
}
if(Q=='I')
{
scanf("%d%d",&x,&y);//在第x个元素前插入y
inslist(L,x,y);//直接调用函数即可
if(ans) continue;//ans=1代表了数据范围不对,跳过本次循环进行下一次
printf("在第%d个位置前插入元素%d得:\n",x,y);
prin(L);
}
}
return 0;
}
/*
测试输入:
10
1 2 3 4 5 6 7 8 9 10
I 3 999
I 2 998
D 999
D 2
D 9
D 999
E
*/
2.单链表删除,插入简易过程
2.1建表头插法
过程:
课本上重点理解代码:
s->next=L-next;
L->next=s;
2.2建表尾插法
嗯,会的话就不用看
过程:
重点代码:
r->next=s;
r=s;
2.3单链表第i位插入元素
//pre代表单链表第i-1位元素
//待插入元素为S
s->next=pre->next;
pre->next=s;
//注意:不能直接令pre->=s,这样单链表会断掉
//所以先另s指向第i项,再令第i-1项(就是pre)指向s
2.4单链表删除第i位元素
pre代表单链表的第i-1项
令r指向pre的下一项,也就是第i+1项
pre->next=r->next;//即:第i-1项指向第i+1项
3.两种存储方法的优缺点
顺序存储特点:容易查询修改元素,不容易对数据元素进行增删。
链式存储优特点:容易对数据元素进行增删,但不易对元素进行查询。
作业题:p75,p76
二、栈与队列
1.栈
1.1概念:
栈是一种限定性线性表,插入与删除仅在表的一端进行。
1.2常用术语:
库函数头文件:#include< stack >
需要std空间
clearstack(s):清空栈s;
push(S,X):在栈顶插入元素s
pop(S,X):删除栈顶元素
gettop(S,X):取栈顶元素赋值给X,该元素不退栈
这些术语只是用来描述过程,写成代码格式是错误的。
1.3 栈的特征:
先进后出
定义的结构体中包含:一维数组存放栈中数据,变量top代表栈顶元素额下标。
相关代码过一遍即可比较简单
2.队列
2.1 概念:
一种限定性线性表,只允许在表的一端插入,而在另一端删除元素。
2.2 常用术语
库函数头文件:#include< queue >
需要std空间
enterqueue(Q,X):在Q队尾插入元素X
gethead(Q,X):取队列队头元素用x带回其值。
2.3队列特征
先进先出,队尾进,队头出。
2.4循环队列(***导员强调过,估计得考,我写细点)
定义队列:Q[max];//max可以认为是一个数
front:指向队头
rear:指向队尾
当rear==max时,认为队列假溢出
(因为随着部分元素出队列,多出空余单元)
当且仅当:rear-front==max时,认为队满
循环特性:当rear+1==max时,令rear==0
通过取模实现:rear=(rear+1)%max ('%'即为mod取模操作)
即:进队时:rear=(rear+1)%max
出队时:front=(front+1)%max
注意:不能通过rear==front来判断是不是队满(也有可能是队列为空)
方法1:损失一个元素空间,使得front和rear不可能相同
此时判断队满条件变为:(rear+1)%max==front,
方法2:新加一个标志量,区别队列是空还是满。
具体代码:
#defien N 100
typedef struct // 循环队列定义
{
int elem[N];
int front; //头指针指示器
int rear; //尾指针指示器
}seq;
//循环队列初始化:Q->front=Q->rear=0;
int entqueue(seq *Q,int x) //循环队列插入操作
{
if((Q->rear+1)%N==Q->front)
return 0;//0定义为失败
Q->elem[Q->rear]=x;
Q->rear=(Q->reaa+1)%N;
return 1;//成功
}
int delqueue(seq *Q,int *x) //删除队头元素,并用x返回其值
{
if(Q->front==Q->rear)
return 0;//队列为空
*x=Q->elem[Q->front];
Q->front=(Q->front+1)%N;
return 1;//成功
}
3.栈与队列容器调用库函数操作