用C++类实现单向链表的增删查和反转操作方法

2020-01-06 17:16:52刘景俊

数据结构这东西,理解起来不算难,但是实现难度就不小了,虽然思路很清晰,但不知道从何下手还有语言的细节问题一直是阻碍初学者的主要障碍(比如我)。今天用了一下午时间终于独立完成了链表操作。

找网上的代码,大多用了结构体,还有些并不适合刚学c++或者数据结构的人看,于是我是用类写的,代码比较符合学生的习惯和水平。

先看类定义


class node
{
public:
  int data;
  node *next;
};
class linklist
{
  node *h;
  ……//一些函数
}

两个类,node用来表示结点,node *next,表示next是指向node型的指针(一些同学看不懂这句,会和构造函数弄混),linklist类是存放头指针和定义操作函数用的。

一、整表的创建

整表创建有两种方法,头插(倒叙)和尾插(顺序),这里只说头插。


void head(linklist &l,int n)
  {
    node *p;
    p=new node;
    l.h=p;//定义头结点和投指针
    p->data=n;//头指针的数据域是结点个数
    p->next=NULL;//最末结点的后继必须为空
    for(int i=0;i<n;i++)//创建n个新结点
    {
      node *q=new node;
      cin>>q->data;
      q->next=p->next;
      p->next=q;//每个新结点都放在头结点后面
    }
  }

二、单结点插入


void insert(linklist &l,int n,int num)
  {
    node *p=l.h;
    for(int i=0;i<n;i++)
    {
      p=p->next;
    }//找到插入的位置
    node *q=new node;
    q->next=p->next;
    p->next=q;
    q->data=num;
  }

三、单结点删除


void del(linklist &l,int n)
  {
    node *p=l.h;
    for(int i=0;i<n-1;i++)
    {
      p=p->next;
    }//找到删除的位置
    node *q=p;
    q=q->next;
    p->next=q->next;
    delete q;//释放空间
  }

四、查找结点


void search(linklist &l,int n)
  {
    node *p=l.h;
    for(int i=0;i<n;i++)
    {
      p=p->next;
    }
    cout<<p->data<<endl;
  }

五、倒置

由于头插是倒叙输出,就想倒置,网上好多代码都是新建一个链表,或者用到尾指针双向链表之类,我觉得不会这么麻烦于是就想了这么个算法


void reverse(linklist l)
  {
    node *p=l.h;
    node *q;
    p=p->next;
    while(p->next)
    {
     q=p->next;
     p->next=q->next;
    // q->next=p;  //如果把下面两句换成这句,就会悲剧。
     q->next=l.h->next;
     l.h->next=q;
    }
  }

一下午时间主要就耽误在这里了,我一开始写的就是注释那句话,后来总是输出头结点的数据,仔细观察发现原来是头指针跟着头结点换到了最后面,然后这个问题通过下面两句解决,保证头指针永远在表头。