C++非循环链表的初始化和反转(指针操作)

非循环链表的C++语言定义

//非循环单链表数据结构C艹类声明

template <typename ElemType>
class LinkList
{
public:
    class LinkNode
    {
    public:
        ElemType data;
        LinkNode *next;
    //  NodePointer next;
    };
    typedef LinkNode * NodePointer;
    // 下面可以添加很多链表操作函数
    void adverse();                                               //非循环单链表的逆置
    void randLinkList();                                        //产生随机链表
    void display(ostream& out) const;
//************************下列为系统自动调用的构造函数和析构函数**************************//
    LinkList();
    virtual~LinkList();
    LinkList(const LinkList<ElemType>& otherL);

protected:
    NodePointer head;
};


//非循环单链表的逆置

template <typename ElemType>
void LinkList<ElemType>::adverse()
{
    NodePointer r,p,q;

    if(!head)
        return;
    r=NULL,p=head,q=p->next;
    while(p)
    {
        p->next=r;
        r=p;
        p=q;
        if(q)
            q=q->next;
    }
    head=r;
}
//随机产生非循环单链表
void LinkList<ElemType>::randLinkList()
{
    clear();
    int i,n;
    int elem[11];
    NodePointer p=head;
    NodePointer s;
    srand((unsigned)time(NULL));
    n=rand()%10+1;
    cout<<"用如下随机数生成非循环单链表:"<<endl;
     for( i=0;i<=n;i++)
     { 
         elem[i]=rand()%100+1;
       cout<<elem[i]<<" ";
      }
    cout<<endl;
    cout<<endl<<"随机生成的非循环单链表为:"<<endl;
    for( i=1;i<=n+1;i++)
        cout<<"[ "<<i<<"] ";
    cout<<endl;
    for(i=0;i<=n;i++)
    {
        s=new LinkNode;
        assert(s!=0);
        s->data=elem[i];
        if(!head)
            head=s;
        else
            p->next=s;
        p=s;
        if(p)
        p->next=NULL;
    }
    p=head;
    while(p)
    {
        while(p->next!=NULL)
        {
        cout<<" "<<p->data<<"->";
        break;
        }       
        while(p->next==NULL)
        {
                cout<<" "<<p->data<<"∧";
                break;
        }
        p=p->next;
    }   
    cout<<endl;
}

使用随机产生的数组elem[i]对链表进行初始化的过程如下:

  for(i=0;i<=n;i++)
    {
        s=new LinkNode;
        assert(s!=0);
        s->data=elem[i];
        if(!head)
            head=s;
        else
            p->next=s;
        p=s;
        if(p)
        p->next=NULL;
    }
    p=head;

看似简单的程序,理解起来对于初学者却很费力,现上传自己的梳理程序流程图如下:
链表初始化流程图
链表的逆置,也体现了指针操作的精髓,其核心思想是:从非循环单链表的第一个结点开始,沿着链表滑动,知道最后一个结点,逐一反转。
具体程序如下:

NodePointer r,p,q;//声明结点指针型的三个指针,分别用来指向当前结点、前结点和后结点

    if(!head)   //如果当前链表的头指针为空,说明链表不存在,程序终止
        return;
    r=NULL,p=head,q=p->next;  //第一次时,当前指针指向首结点,也就是等于头指针
    while(p)
    {
        p->next=r;//对当前结点的指针赋值,指向前结点,当然首节点反转后成为尾结点,其next指针为NULL
        r=p;  //r,p,q依次向后滑动
        p=q;
        if(q)
            q=q->next;
    }
    head=r;   当p=q=NULL时,说明当前结点已经滑动至尾结点之外,此时,只需要将r指针赋值给头指针即可

具体流程图自己在草稿纸上消化如下:
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值