线性表的链式储存(单链表c++实现)

  1. 单链表的类型定义
    typedef int TypeDate;  //定义TypeDate为int型
    typedef struct linknode
    {
      DateType date;         //定义结点的数据域
      struct linknode *next; //定义结点的指针域
    }linklist;

    上面定义的LinkList是结点类型,如果想定义一个指向该节点类型的指针head,c++中的语言如下:

    LinkList *head;

    如果想动态申请一个节点空间,并让指针head指向该结点空间,语句如下:

    head=(LinkList *)malloc(sizeof(LinkList));

    这样,head指针就指向该节点了,则这个结点的数据域为head->date或是(*head ).date,而指针域为head->next(*head ).next.

  2. 单链表的初始化:单链表的初始化即构造一个仅包含头结点的空单链表。其过程是首先申请一个结点并让指针head指向该结点,然后将他的指针域赋为空,最后返回头指针head。其算法描述如下:
    LinkList *InitList()
    {
      LinkList *head;
      head=(LinkList *)malloc(sizeof(LinkList)); //动态分配一个节点空间
      head->next=NULL;
      return head;          //头结点指针域为空,表示空链表
    }
  3. 单链表的建立:头插法建表。链表与顺序表不同,它是一种动态管理的储存结构,链表中的每个结点占用的储存空间不是预先分配的,而是运行时根据系统需求生成的。因此,建立在初始化链表后,建立线性链表从空表开始,每读入一个有效数据则申请一个结点s,并将读取到的数据存放在新结点s的数据域中,然后将新节点插入到当前链表head的表头上,直到循环结束为止。
    void CreateList (LinkList *head ,int n)
    {
     LinkList *s;
     int i;
     cout<<"请输入"<<n<<"个整数"<<endl;
     for(i=0;i<n;i++)
      { 
         s=(LinkList *)malloc(sizeof(LinkList));    //生成新结点
         cin>>s->date;                              //读入新节点数据域
         s->next=head->next;                        //将头结点的指针域存入新结点的指针域
         head->next=s;                              //头插法的具体表现,将新结点的地址存入头结点的 
                                                    // 指针域
      }
    cout<<"链表插入成功!"<<ednl;
    }
  4. 尾插法建表:头插法建表虽然算法简单容易理解,但生成的链表中结点的次序和原来输入的次序相反。而尾插法建立链表可实现次序的一致,该算法依旧从空表开始,但需增加一个尾指针last,使其指向当前链表的尾结点。其过程是:每读入有效的数据则申请一个结点s,并将新结点插入到当前链表尾部(last指针所指的结点后面),直到循环结束为止。
    void CreateListL (LinkList *head,int n)
    {
       LinkList *s,*last;
       int i;
       last=head;                           //开始时last指向头结点
       cout<<"请输入"<<n<<"个数:"<<endl;
       for(i=0;i<n;i++)
       {
          s=(LinkList *)malloc(sizeof (LinkList));
          cin>>s->date;
          s->next=NULL;
          last->next=s;               //last指针域指向新结点,即将新结点插入表尾
          last=s;                     //s为新的表尾
       }
      cout<<"线性表建立成功!"<<endl;
    }
  5. 求表长操作:因为链表是链式结构,所以链表中元素个数不是已知的。想求表中元素个数还得设一个计算变量j,将一个指针p先指向链表中第一个元素,当p不为空时,循环将p指针向后移,j+1,循环结束后j值即为链表长度。
    int LengthList(LinkList *head )
    {
       LinkList *L=head->next;
       int j=0;
       while(L!=NULL)
       {
         j++;
         p=p->next;
       } 
    return j;
    }
  6. 查找操作:按值查找:从链表中第一个元素结点开始,由前向后依次比较单链表中各结点数据域中的值,某结点数据域中的值与给定的值x相等,则循环结束:否则继续向后比较直到表结束,然后判断指针p,若p不为空表示单链表中有x结点,输出查找成功的信息并输出x所在表中的位置;否则输出查找失败的信息。
    void Locate(LinkList *head, DateType x)
    {
       int j=1;
       LinkList *p;
       p=head->next;
       while(p!=NULL && p->date!=x)
       {
         p=p->next;
         j++;
       }
       if(p!=NULL)
       cout<<"在链表中第"<<j<<"个位置找到了值为"<<x<<"的结点!"<<endl;
        else
        cout<<"链表不存在值为"<<x<<"的结点!"<<endl; 
    }
  7. 插入操作:在指针所指的结点后插入新结点。若要在链表中指针p所指位置后面插入一个结点,则插入操作步骤如下:1.先将结点s的指针域指向结点p的下一个结点(s->next=p->next); 2.再将结点p的指针域改为指向新结点s(p->next=s).
    void InsList(LinkList *head,int i,DateType x)
    {
       int j=1;
       LinkList *s,*p;
       p=head;
       while(p->next!=NULL && j<i-1)
       {
         p=p->next;
         j++;
       }
       if(p!=NULL)
      {
       s=(LinkList *)malloc(sizeof(LinkList));
       s->date=x;
       s->next=p->next;
       p->next=s;
       cout<<"插入元素成功!"<<endl;
      }
    else
     cout<<"插入元素失败!"<<endl;
    }
  8. 删除操作:删除操作实现首先通过循环定位求出第i结点的前驱结点(第i+1结点)p的地址,然后将指针s指向被删除的结点,修改p->next指针,使其指向s后的结点,最后释放指针s所指结点。

    void DelList(LinkList *head,int i)
    {
       itn j=1;
       DateType x;
       LinkList *p=head,*s;
       while(j<i-1 && p->next!=NULL)
       {
          p=p->next;
          j++;
       } 
       if(j==i-1 && p->next!=NULL)
       {
          s=p->next;
          x=s->date;
          p->next=s->next;
          free(s);//释放所删除结点的空间
          cout<<"删除第"<<i<<"个位置上的元素"<<x<<",成功!"<<endl;
       }
       else
      cout<<"删除失败!"<<endl;
    }
  • 单链表的输出操作:即扫描单链表,输出各元素的值。

    void PriList(LinkList *head)
    {
      LinkList *L=head->next;
      while(L->next!=NULL)
      {
        cout<<L->date<<"   ";
        L=L->next;
      }
    cout<<endl;
    }

    注意,通过上面的链表基本操作可知:

  • 在单链表插入,删除一个结点,必须知道他的前驱结点;

  • 单链表不具备按序号随机访问的特点,只能从头指针开始一个个顺序进行。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值