单链表建立(头插法,头插法,用数组),求长,插入,删除,输出,释放(递归释放和循环释放),归并(递增和递减)

学习地址:http://blog.csdn.net/stpeace/article/details/8091123
#include<iostream>

using namespace std;

typedef struct LNode
{
        int data;
        struct LNode *next;
}LNode,*List;

List createList()//创建链表
{
     LNode *head,*p1,*p2;
     p1=p2=head=new LNode;//分配内存,head指的是头结点,头结点不存放数据
     
      int a;
      cin>>a;
      while(0!=a)//设置一个结束标志用于创建链表
       {
               p1->data=a;
               p2->next=p1;//这时p2是一个新节点,p1又是下一个节点
               p2=p1;//把完成的节点赋给p2,使其成为一个节点
               p1=new LNode;
               cin>>a;
        }
        p2->next=NULL;

        return head;
}

int getLength(List p)//求链表的长度,不包括头结点
{
      int length=0;
      while(NULL!=p->next)
      {
           length++:
           p=p->next;//前移
       }
       return length;
}

//把元素elem插入到pos位置
List insert(List p,int pos,int elem)//向链表中插入元素
{
     int length=getLength(p);//求得长度
     if(pos<1||pos>length+1)//length不包括头结点,length为1即表示第一个节点
     {
           cout<<"error"<<endl;
           exit(1);//退出
     }
     
      LNode *p1=p->next;//elem后的那个节点
      LNode *p1=p;//elem前的那个节点
      int i;
      for(i=0;i<pos-1;i++)//链表只能一个个找
      {
         p2=p1;//p2在前,p1在后
         p1=p1->next;
       }

      LNode *s=new LNode;
      s->data=elem;

      p2->next=s;
      s->next=p1;//调整指向
 
      return p;
}

List del(List p,int a)//删除指定值所指的节点
{
       LNode *p1=NULL,p2=NULL;
       if(NULL==p->next)
       {
             return p;//这里p是最后一个节点
       }

       p1=p1->next;//a的后一个节点
       p2=p;//a前一个节点,刚开始时也相当于头结点

       while(NULL!=p1&&a!=p1->data)
       {
              p2=p1;
              p1=p1->next;//这两段代码实现了节点前移
       }

        if(NULL=p1)//表示已到最后一个节点
        {
               cout<<"not found"<<endl;
        }
        else
        {
              p2->mext=p1->next;
              delete p1;
         }
         return p;
}

void release(List p)//递归释放链表
{
       if(NULL==p->next)
       {
               delete p;
        }
        else
        {
             release(p->next);//释放节点
        }
}

void Xrelease(List p)
{
       List temp;//temp是指向一个结构体数据的指针,p传进来的是指向头结点的指针
       while(p)
       {
          temp=p;
          p=p->next;
          delete temp;//temp是一个指针,释放p指向的那个地址
       }
}

 void print(List p)//打印链表
{
      while(NULL!=p->next)//成立,p表示最后一个节点
      {
             cout<<p->next->data<<endl;
             p=p->next;
      }
}

//递增归并链表
void merge1(LNode *A,LNode *B,LNode *&C)//A,B,C都是头结点
{
     LNode *p=A->next;//指向最小节点
     LNode *q=B->next;
     LNode *r;//r始终指向C的终端节点(每增加一个节点后的终端节点)
     C=A;//用A的头结点做C的头结点
     C->next=NULL;
     free(B);//用指针指向B的第一个有效节点,然后释放头结点
     r=C;
   
     while(p!=NULL&&q!=NULL)
     {
           if(p->data<=q->data)//一个一个比较
            {
                  r->next=p;p=p->next;
                  r=r->next;
            }
             else
            {
                 r->next=q;q=q->next;
                 r=r->next;
             }
     }
      r->next=NULL;

     if(p!=NULL)  r->next=p;//当一个链表插入完成后,另一个链表补到后面
     if(q!=NULL)  r->next=q;
}

//使用尾插法,用数组中的元素建立链表
List createListW(LNode *&C,int a[],int n)
{
     LNode *s,*r;//s指向新申请的节点,r始终指向C的终端节点
     int i;
     C=new LNode;
     C->next=NULL;
     r=C;//r指向头结点,此时头结点就是终端节点

      for(i=0;i<n;i++)
      {
            s=new LNode;
            s->data=a[i];
            r->next=s;
            r=r->next;
      }
      r->next=NULL;

       return C;
}

//利用数组元素,使用头插法建立链表,头插法从头部开始插入,得到的链表的数据将是倒过来的
List createListT(LNode &*C,int a[],int n)
{
      LNode *s;
      int i;
      C=new LNode;
      C->next=NULL;

      for(i=0;i<n;i++)
      {
          s=new LNode;
          s->data=a[i];

          s->next=C->next;//s的指针域指向了C了,C->next为C的指针域
          C->next=s;
      }
          return C;
}

//头插法实现递减
List merge5(LNode *A,LNode *B,LNode *&C)
{
       LNode *p=A->next;
       LNode *q=B->next;
       LNode *s;
       C=A;
      C->next=NULL;
      free(B);

      while(p!=NULL&&q!=NULL)
      {
             if(p->data<=q->data)
             {
                   s=p;p=p->next;
                   s->next=C->next;
                   C->next=s;
              }
              else
              {
                    s=q;q=q->next;
                    s->next=C->next;
                    C->next=s;
              }
       }
        while(q!=NULL)
        {
             s=q;q=q->next;
             s->next=C->next;
             C->next=s;
         }
         while(p!=NULL)
         {
            s=p;p=p->next;
            s->next=C->next;
            C->next=s;
         }
      return C;
}


int main()
{
      List head;
      head=createList();
      print(head);

      int a; 
      a=getLength(head);

      int b=3;
      insert(head,3,b);

      int c=5;
      del(head,3,b);

      List head3;
      List head1=createList();
      List head2=createList();
      merge1(head1,head2,head3);

      release(head);//Xrelease(head);

      List head4;
      int d[5]={1,2,3,4,5};
      createListW(head,d,5);

     List head5;
     int e[5]={4,5,6,7,8};
     createListT(head5,e,5);

     merge5(head1,head2,head3);

     return 0;

}

那个createList的函数中,p1=new Node;这行代码应该在p1->data=a;这行代码的上面。这样头结点才不会有数据。源代码修改不方便,故在后面说一下

 

 

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盼盼编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值