数据结构与算法分析

目录

线性表:

顺序表:

链表:

循环链表:

双向链表

栈和队列

顺序栈

链栈

队列

顺序队列


线性表:

顺序表:

链表:

循环链表:

即最后结点的指针域指向头结点

使用rear标志尾结点-------->这样使得找头结点和尾结点都变得容易-------->尾结点为rear,头结点为rear->next

在循环链表第i个元素后插入元素x

void insert(linklist *head, datatype x, int i)  //即这一版本是需要自己遍历出i结点
{
    linklist *s,*p;
    int j;
    s=(linklist *s)malloc(sizeof(linklist));
    s->data=x;
    p=head;
    for(j=0;j<i;j++)          //这里就是在找出i结点
    {
        p=p->next;
    }
    s->next=p->next;
    p->next=s;
}

双向链表

不仅含有指向直接后趋的指针next,还有指向直接前趋的指针prior

由于加入了prior指针,所以在删除和增加结点时,操作有一些不同

删除结点
void delete(linklist *p)
{
    p->prior->next = p->next;
    p->next->prior = p->prior;
    free(p);        //删除时一定要记住释放p的空间
}

双向结点有一个好处:可以在某一个元素x前插入元素i

栈和队列

限定仅在表尾进行插入和删除运算的线性表,表尾为栈顶,表头为栈底

顺序栈

由于栈底是不变的,只需要记住栈顶的位置即可

struct Stack{
    datatype elements[maxsize];
    int Top;
};

即这里的Top就标记了栈的大小

栈的运算

置空栈
strut Stack *SetNullS(strut Stack *S){
      S->Top=-1;
      return S;
}
进栈,将元素i插入栈s的栈顶
struct Stack *PushStack(struct Stack *s, int i){
    S->Top++;
    S->elements[S->Top]=i   //这里注意必须要指出在S中
    return S;
}

链栈

问题:为了防止溢出现象,栈的容量必须设置的很大,但这样会浪费很多的空间----->链栈

建立栈

strut Node{          //这里是建立结点
    datatype element;
    struct Node *next;      //这里是指next依旧是一个结点
};

进栈(这里的代码需要去理解一下)

struct Node *PushL(struct Node *Top,datatype i){
    struct Node *p;
    p=(struct Node *)malloc(sizeof(struct Node));
    p->element=i;
    p->next=Top;
    Top=p;
    return Top;
}

出栈(这个是返回结点)

struct Node *delete(struct Node *Top){
    struct Node *ret;
    ret=(struct Node *)malloc(sizeof(struct Node));
    ret=Top;
    Top=Top->next;
    retrun ret;
}

下面是返回当前的结点的值

datatype *PopL(struct Node *Top){
    datatype *ret;
    ret=(datatype *)malloc(sizeof(datatype));
    if(Top=NULL){
        printf("underflow");
        return NULL;
    }
    else{
        *ret=Top->element;     //注意这里必须为*ret,而不是ret
        Top=Top->next;
        return ret;
    }
}
        

这里需要在学习一下若子函数返回值是两个时的知识

队列(这里需要做几道题练习一下)

在表的一段进行插入,另一端进行删除

顺序队列

实际上是运算受限的顺序表,由于队尾与队头的位置均是变化的,需要设置两个指针分别表示当前队头元素和队尾元素在数组中的位置。

struct sequeue{
    datatype data[MAXSIZE];
    int front,rear;
};
struct sequeue *sq;

注意:这里的头指针总是指向开头的前一个元素

问题:被删元素的空间在该元素被删之后就再也用不到了

解决方法:在每次出对是,将整个队列的元素向前移动一个位置,或者在发生假上溢时,将整个队列中的元素向前移动直至头指针为-1,但这两种方法都会造成大量元素的移动,所以在实际操作中很少使用。----->将队列变成一个首尾相接的圆环。

具体操作:若当前尾指针等于数组的上界,则再做入队操作时,令尾指针等于数组的下界,利用被删除的元素的空间。(利用模的概念)

sq->rear=(sq->rear+1)%MAXSIZE        //这是入队时防止上溢采取的措施
sq->front=(sa->front+1)%MAXSIZE        //同理出队时也是如此

判断队列为满与队列为空的语句都是:sq->rear==sq->front---------->引入一个标志变量以区分时空队列还是满队列/入队前测试队尾指针再循环意义下加一是不是等于头指针(这个方法比较好)

链队列

队列的链式结构

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值