数据结构学习笔记(未整理)

一、顺序表

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.栈与队列容器调用库函数操作

写给明月
写给明月
写给明月

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值