zoukankan      html  css  js  c++  java
  • 线性表和链表

    线性表的定义:
    (List)

    typedef int position;

    typedef struct LNode* PtrToNode;
    typedef PtrToNode List;

    struct LNode{//数据从data[0]开始,last记录线性表中最后一个元素在表中的位置,表长为last+1;
    int date[maxsize];
    position last;//表空时,last = -1;
    };

    以下是顺序表的主要操作以及实现:
    1.初始化(构造一个空表)
    List MakeEmpty()
    {
    List L;
    L = (List)malloc(sizeof(struct LNode));
    L->last = -1;//表示表空
    return L;
    }

    2.查找:在线性表中,查找与给定值x相等的数据元素。查找成功就返回X在线性表中的下标,否则返回错误信息error

    #define error -1
    position Find(List L, int x)
    {
    position i =0;//i记录下标,从0开始
    while(i<=L->Last && L->date[i]!=x)
    i++;
    //跳出while时说明:要么i>last,要么x=date[i]
    if(i>L->Last)//检查i是否越界
    return error;
    else
    return i;
    }

    3.插入:在表的第i(1<=i<=n+1)个位置上插入一个值为x的元素,
    将ai-an向后移动1位,再将x插入空出的序列,修改last指针.

    bool insert(List L,int x,int i)
    {//再位序为i的元素(下标是i_1)前插入一个元素,之后原来位序为i的元素位序就是i+1;
    position j;

    if(L->last==maxsize-1)
    { printf("表满");
    return false;
    }

    if(i<1||i>last+2)
    {//last是最后一个元素的下标
    printf("插入位序不符合");
    return false;
    }

    for(j = L->last;j>=i;j--)//后移元素,从后往前移动
    {
    L->date[j+1]=date[j];
    }

    L->date[i-1]=x;//第i个元素下标是i-1
    L->last++;

    return true;
    }

    4.删除:将表中位序为i(1<=i<=n)的元素删除,表长变成n-1;
    元素前移,覆盖ai,再修改last;

    bool delet(List L, int i)
    {
    position j;
    if(i<1||i>L->last+1)
    {
    printf("位序%d不存在",i);
    return false;
    }

    for(j=i;j<=L->last;j++)//第i个元素的下标是i-1,
    {
    L->date[j-1]=L->date[j];
    }

    L->last++;
    return true;
    }

    单链表

    definetion:
    typedef struct LNode* PtrToLNode;//起个别名,注意这是一个指针类型
    struct LNode{
    int date;
    PtrToLNode next;//next是指针类型;
    }
    typedef PtrToNode position;//这里的位置是结点的位置
    typedef PtrToNode List;

    1.求表长:
    再线性表中,直接返回last+1就可以,但是再链表中要将表从头到尾遍历一遍。
    p是一个移动的指针,cnt速死计数,当后面不再有结点时,cnt的值就是结点的个数.
    int length(List L)
    {
    position p;

    int cnt=0;
    p = L;

    while(p)//只要p不为空
    {
    p = p->next;
    cnt++;
    }

    return cnt;
    }

    2.1 按序号查找findkth
    从表的第一个结点开始遍历,直到找到第k个结点
    #define error -1;


    int findkth(List L)
    {
    position p;
    int cnt = 1;
    p = L;

    while(p&&cnt<k)//p不为空的指针且cnt<k;
    {
    p=p->next;
    cnt++;
    }

    if(cnt==k)//跳出循环时要么p为空要么cnt=k;
    return p->date;
    else
    error;
    }

    2.2按值查找:从头到尾的遍历直到找到为止;
    从第一个结点开始判断他的值是不是x,是就返回该结点的位置(这个位置是一个地址),否则即指向下一个结点;

    #define error null;
    position find(List L, int x)
    {
    position p =L;
    while(p||p->date!=x)
    {
    p = p->next;
    }
    //跳出循环时,要么p是null,要么找到了x
    if(p)//判断p是不是null
    return p;
    else
    return error;
    }

    3:插入
    再位序为i(1<=i<=n+1)前插入一个元素x,i为1是代表插入表头,i是n+1是代表是表尾。
    若i不为1,这找到位序为i-1的结点pre;若存在,则申请一个新结点并数据域上填上相应的x的值,
    然后新结点插入pre之后,返回结果链表
    ps:以下代码假设没有空的头结点

    #define error null;
    List insert(List L, int x, int i)
    {
    position tmp, pre;定义两个指针

    tmp = (position)malloc(sizeof(struct LNode));
    tmp->date = x;//tmp是待插入的结点

    if(i==1)//判断是不是第一个结点,第一个结点特殊处理
    {
    tmp ->next = L;
    return tmp;
    }
    else{//查找位序为i-1的结点
    int cnt =1;//位序从1开始
    pre = L;
    while(pre&&cnt<i-1)
    {
    pre = pre->next;
    cnt++;
    }
    // 跳出while()时,要么pre为空,要么cnt = i-1
    if(pre==null||cnt!=i-1)//
    {
    printf("所找的结点不在L中");
    free(tmp);

    return error;
    }
    else//找到了待插入结点的前一个结点
    {//以下是插入代码
    tmp->next = pre->next;
    pre->next = tmp;
    return L;
    }

    }
    }

    3.2带空的头节点的插入,不需要将插入第一个结点当作是特殊情况。
    带上空的头节点的好处是:无论再哪里插入或者是删除,
    L的值一直是指向固定的空结点,不会改变。

    bool Insert(List L, int x, int i)
    {
    position tmp, pre;
    int cnt =0;

    pre =L;
    while(pre&&cnt<i-1)//查找第i-1个结点
    {
    pre=p->next;
    cnt++;
    }

    if(pre==null||cnt!=i-1)
    {
    printf("所查找的结点不在L中");
    return false;
    }
    else//找到了待插入结点的前一个结点,若i为1,则pre指向表头.
    {
    tmp = (position)malloc(sizeof(struct LNode))
    tmp ->date = x;
    tmp->next = pre->next;
    pre->next = tmp;
    return true;
    }

    }

    4删除
    在单链表中删除指定位序为i的元素,需要找到i的前一个元素,然后再删除i

    bool delete(List L, int i)
    {//这里默认L右头节点
    position tmp, pre;

    int cnt =0;

    pre = L;//pre指向头节点,,cnt从0开始计数;
    while(pre&&cnt<i-1)
    {
    pre = pre->nexxt;
    cnt++;
    }

    if(pre==null&&cnt!=i-1)//第i个结点的下标是i-1
    {
    printf("不在L中");
    return false;
    }
    else
    {
    tmp = pre->next;
    pre->next = tmp->next;
    free(tmp);
    return true;

    }
    }

  • 相关阅读:
    【BJOI2018】求和
    【洛谷P1613】跑路
    【NOI2001】食物链
    【NOI2002】银河英雄传说
    【POJ1456】Supermarket
    【NOIP2013】货车运输
    【CH#56C】异象石
    【POJ3417】Network
    【APIO2010】巡逻
    【CH6201】走廊泼水节
  • 原文地址:https://www.cnblogs.com/qinmin/p/12416607.html
Copyright © 2011-2022 走看看