精华内容
下载资源
问答
  • C语言实现不带头节点的单链表

    千次阅读 2018-07-11 20:45:17
    我们介绍了基于静态数组和动态数组顺序表,顺序表频繁查询而插入删除动作少情况下,顺序表也适用于进行尾插时候,因为相对于链表而言,顺序表在进行尾插时,顺序表需要通过遍历来找到最后一个插入点,比较而...

    在上两篇文章中,我们介绍了基于静态数组和动态数组的顺序表,顺序表频繁查询而插入删除动作少的情况下,顺序表也适用于进行尾插的时候,因为相对于链表而言,顺序表在进行尾插时,顺序表不需要通过遍历来找到最后一个插入点,比较而言,顺序表尾插效率高。
    但是,在进行头插和中插时,顺序表需要将插入元素位置之后的元素整体后移才能插入数据,这样做在有大量插入删除场景下即为麻烦且效率低,因此,提出了链表的思想。而链表在头插或者中插时,只需要创建一个新节点,然后将节点链入所插入位置即可。

    链表概述

    链表是一种常见的数据结构。数组可以存放数据,但是数组存放数据时必须提前指定数组包含元素个数,即数组长度。但是数组保存数据的缺点在于如果要保存元素大于数组大小时,则不能将所有内容保存入数组,而当要保存元素远小于数组大小时,又造成了空间的浪费。而链表其存储元素个数不受限定,当进行添加元素时,存储个数随之增加。
    链表是一种链式存储的线性表,用一组地址任意的存储单元存放线性表的数据元素,称存储单元为一个节点。

    typedef int DataType;
    
    typedef int DataType;
    
    typedef struct LinkNode
    {
        DataType _data;//当前节点保存数据
        struct LinkNode* _pNext;//指向链表中下一结点的指针
    
    }Node;

    如下图,为链表结构示意图:
    这里写图片描述
    在链表中有一个头指针变量,图中head表示的就是头指针,这个指针变量保存一个地址。从图中的箭头可以看到该地址为一个变量的地址,也就是说头指针指向一个变量。这个变量称为元素,在链表中每一个元素包括两个部分:数据部分和指针部分。数据部分用来存放元素所包含的数据,而指针部分用来指向下一个元素。最后一个元素指针指向NULL,表示指向的地址为空。
    从图可以看到,head头结点指向第一个元素,第一个元素中的指针又指向第二个元素,第二个元素的指针又指向第三个元素的地址,第三个元素的指针指向第四个元素,第四个元素的指针就指向为空。

    链表的分类

    • 单链表
    • 双向链表
    • 双向循环链表

    需要注意的是,上述三种链表都有两种形式,分别为带头结点和不带头结点。

    这里写图片描述

    C语言实现不带头节点的单链表

    具体代码实现如下:

    #pragma once 
    
    #include <stdio.h>
    #include <assert.h>
    #include <malloc.h>
    
    /***************************************/
    
    //链表的定义
    typedef int DataType;
    
    typedef struct LinkNode
    {
        DataType _data;//当前节点保存数据
        struct LinkNode* _pNext;//指向链表中下一结点的指针
    
    }Node;
    
    /***************************************/
    
    //链表的初始化
    void LinkListInit(Node** pHead);
    
    //创建新结点
    Node* LinkListCreatNode(DataType data);
    
    //销毁结点
    void LinkListIDestroyNode(Node** pHead);
    
    //遍历打印链表
    void LinkListPrint(Node** pHead);
    
    //尾插元素
    void LinkListPushBack(Node** pHead, DataType data);
    
    //尾删元素
    void LinkListPopBack(Node** pHead);
    
    //头插元素
    void LinkListPushFront(Node** pHead, DataType data);
    
    //头删元素
    void LinkListPopFront(Node** pHead);
    
    //查找元素
    size_t LinkListFind(Node** pHead, DataType data);
    
    //任意位置的插入
    void LinkListInsert(Node** pHead, DataType data, Node* pos);
    
    //任意位置的删除
    void LinkListErase(Node** pHead, Node* pos);
    
    //求单链表长度
    size_t LinkListSize(Node** pHead);
    
    //销毁一个单链表
    void LinkListDestroy(Node** pHead);
    
    //判空
    size_t LinkListEmpty(Node** pHead);
    
    
    /***************************************/
    //链表的初始化
    void LinkListInit(Node** pHead)
    {
        //考虑指针为空
        assert(pHead);
        *pHead = NULL;
    }
    
    //创建新结点
    Node* LinkListCreatNode(DataType data)
    {
        Node* pNewNode = (Node*)malloc(sizeof(Node));
        assert(pNewNode);
    
        pNewNode->_data = data;
        pNewNode->_pNext = NULL;
        return pNewNode;
    }
    
    //销毁结点
    void LinkListIDestroyNode(Node** pHead)
    {
        //释放该结点,并将头指针指向NULL,防止出现野指针
        free(pHead);
        *pHead = NULL;
    }
    
    //遍历打印链表
    void LinkListPrint(Node** pHead)
    {
        Node* pCur = *pHead;
        for (pCur; pCur != NULL; pCur = pCur->_pNext)
        {
            printf("%d--->", pCur->_data);
        }
        printf("NULL\n");
    }
    
    //尾插元素
    void LinkListPushBack(Node** pHead, DataType data)
    {
        Node* NewNode = LinkListCreatNode(data);
        assert(pHead);
        //如果链表为空,则直接让头指针指向新申请的节点即可
        if (*pHead == NULL)
        {
            *pHead = NewNode;
            return;
        }
        //否则从头开始遍历链表,直到当前节点的指针域指向NULL,然后让当前节
        //点的指针域指向新申请的节点即可
        Node* pTail = *pHead;
        while (pTail->_pNext)
        {
            pTail = pTail->_pNext;
        }
        pTail->_pNext = NewNode;
    }
    
    //尾删元素
    void LinkListPopBack(Node** pHead)
    {
        assert(pHead);
        if (*pHead == NULL)
        {
            printf("链表为空,无法删除!\n");
            return;
        }
        //如果当前只有一个结点,则释放该结点,
        //并将头指针指向NULL,防止出现野指针--相当于销毁结点
        if ((*pHead)->_pNext == NULL)
        {
            free(pHead);
            *pHead = NULL;
        }
        //定义两个指针,依次向后走
        //pTail不为空时,将其前一个结点指针pPreTail赋给pTail
        //当pTail为空时,释放pTail,pPreTail指向NULL
        Node* pTail = *pHead;
        Node* pPreTail = NULL;
        while (pTail->_pNext)
        {
            pPreTail = pTail;
            pTail = pTail->_pNext;
        }
        free(pTail);
        pPreTail->_pNext = NULL;
    
    }
    
    //头插元素
    void LinkListPushFront(Node** pHead, DataType data)
    {
        assert(pHead);
        Node* NewNode = LinkListCreatNode(data);
        NewNode->_pNext= (*pHead);
        *pHead = NewNode;
    }
    
    //头删元素
    void LinkListPopFront(Node** pHead)
    {
        Node* pDel = NULL;
        assert(pHead);
        //考虑链表为空情况
        if ((*pHead) == NULL)
        {
            printf("链表为空!无法删除!\n");
            return;
        }
        pDel = *pHead;
        *pHead = pDel->_pNext;
        free(pDel);
    }
    
    //查找元素
    size_t LinkListFind(Node** pHead, DataType data)
    {
        assert(pHead);
        //考虑链表为空的情况
        if (*pHead == NULL)
        {
            printf("链表为空!无法查找!\n");
            return -1;
        }
        Node* pFind = *pHead;
        while (pFind && pFind->_data != data)
            pFind = pFind->_pNext;
        if (pFind != NULL)
        {
            printf("找到了数据%d\n", pFind->_data);
            return 1;
        }   
        else
            printf("没有找到数据%d\n",data);
        return -1;
    
    }
    
    //任意位置的插入
    void LinkListInsert(Node** pHead, Node* pos, DataType data)
    {
        assert(pHead);
        //考虑pos位置的合法性
        assert(pos);
        //考虑空链表情况
        Node* pNewNode = LinkListCreatNode(data);
        if (*pHead == NULL)
        {
            *pHead = pNewNode;
            return;
        }
        if (pos == NULL)
        {
            LinkListPushBack(pHead, data);
            return;
        }
        if (pos == *pHead)
        {
            LinkListPushFront(pHead, data);
            return;
        }
        Node* pCur = *pHead;
        while (pCur->_pNext != NULL)
        {
            if (pCur->_pNext == pos)
            {
                pNewNode->_pNext = pos;
                pCur->_pNext = pNewNode;
            }
            pCur = pCur->_pNext;
        }
        return;
    }
    
    //任意位置的删除
    void LinkListErase(Node** pHead, Node* pos)
    {
        assert(pHead);
        assert(pos);
        //考虑链表为空
        if ((*pHead) == NULL)
        {
            printf("链表为空!无法删除!\n");
            return;
        }
        if (pos == (*pHead))
        {
            LinkListPopFront(pHead);
            return;
        }
        Node* pE = *pHead;
        while ( pE != NULL)
        {
            if (pE->_pNext != NULL)
            {
                pE->_pNext = pos->_pNext;
                LinkListIDestroyNode(pos);
                return;
            }
            pE = pE->_pNext;    
        }
        return;
    }
    
    //求单链表长度
    size_t LinkListSize(Node** pHead)
    {
        assert(pHead);
        Node* pSize = *pHead;
        size_t count = 0;
        while (pSize != NULL)
        {
            pSize = pSize->_pNext;
            count++;
        }
        printf("链表长度为%d\n",count);
        return count;
    }
    
    //销毁一个单链表
    void LinkListDestroy(Node** pHead)
    {
        assert(pHead);
        Node* pDpre = NULL;
        Node* pD = *pHead;
        //定义两个指针同时向链尾走,pD不为空时,用pDpre标记pD
        //pD不断向后移同时释放pDpre,直至将整个链表结点全部释放
        while (pD)
        {
            pDpre = pD;
            pD = pD->_pNext;
            free(pDpre);
        }
        //切记将头指针指向空,不然将变成野指针
        *pHead = NULL;
    }
    
    //判空
    size_t LinkListEmpty(Node** pHead)
    {
        assert(pHead);
        return ((*pHead) == NULL);
    }
    
    
    /***************************************/
    //测试部分
    void LinkListTest()
    {
        Node* p;
        LinkListInit(&p);
    
        LinkListPushBack(&p, 1);
        LinkListPushBack(&p, 2);
        LinkListPushBack(&p, 3);
        LinkListPushBack(&p, 4);
        LinkListPushBack(&p, 5);
        LinkListPrint(&p);
    
        LinkListPopBack(&p);
        LinkListPrint(&p);
    
        LinkListPushFront(&p, 5);
        LinkListPushFront(&p, 6);
        LinkListPrint(&p);
    
        LinkListPopFront(&p); 
        LinkListPopFront(&p);
        LinkListPrint(&p);
    
        LinkListFind(&p, 2);
        LinkListFind(&p, 5);
    
        LinkListSize(&p);
    
        LinkListInsert(&p,p,8);
        LinkListPrint(&p);
    
    
        //LinkListErase(&p,2);
        //LinkListPrint(&p);
    
    
    }
    展开全文
  • 作为刚刚开始学习数据结构小白,很是迷茫,通过参考《大话数据结构》等,现在对单链表的创建做一个总结,以备日后复现。如果下面内容有错误,还请多多指出。 定义结点 typedef struct LNode{ int data; struct...

    说明

    最近开始学习数据结构相关的知识,看到单链表的内容,对于单链表的创建的头插法和尾插法两种方法,又根据单链表是否带有头结点,这样会产生四种情况。作为刚刚开始学习数据结构的小白,很是迷茫,通过参考《大话数据结构》等,现在对单链表的创建做一个总结,以备日后复现。如果下面的内容有错误,还请多多指出。

    定义结点

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

    单链表创建之头插法:

    用头插法创建带有头结点的单链表
    //用头插法创建带有头结点的单链表
    LNode * Createhead1(int length)
    {
        int data[12] ={0,1,2,3,4,5,6,7,8,9,10,11};  //为了测试方便,自己写了数组来测试,也可以用下面的随机数来创建
        LNode * p;
        //srand(time(0)); // 初始化随机数种子
        if(length < 1)
            return NULL;
        LNode *head  = (LNode*)malloc(sizeof(LNode));
        head->next = NULL;
        int i = 1;
        while(i<=length)
        {
            p = (LNode*)malloc(sizeof(LNode));
            //p->data = rand()%100+1; //随生成100以内的数字
            p->data = data[i];
            p->next = head->next;
            head->next = p;
            i++;
        }
        return head;
    }
    
    用头插法创建无头结点的单链表
    //头插法无头结点创建
    
    LNode *Createhead2(int length)
    {
        int data[12] ={0,1,2,3,4,5,6,7,8,9,10,11};
        LNode*p;
        //srand(time(0));
        if(length<1)
            return NULL;
        LNode *first = (LNode*)malloc(sizeof(LNode));
        first->next = NULL;
        first->data = data[0];
        int i = 1;
        while(i<length)
        {
            p = (LNode*)malloc(sizeof(LNode));
            //p->data = rand()%100+1;
            p->data = data[i];
            p->next = first;
            first = p;
            i++;
        }
        return first;
    }
    

    单链表创建之尾插法:

    用尾插法创建带有头结点的单链表
    //尾插法带头结点创建
    
    LNode*Createrail1(int length)
    {
        int data[12] ={0,1,2,3,4,5,6,7,8,9,10,11};
        LNode *p;
        //srand(time(0));
        if(length<1)
            return NULL;
        LNode *head =(LNode*)malloc(sizeof(LNode));
        head->next = NULL;
        LNode *temp = head;
        int i = 1;
        while(i<=length)
        {
            p = (LNode*)malloc(sizeof(LNode));
            //p->data = rand()%100+1;
            p->data = data[i];
            temp->next = p;
            temp = p;
            i++;
        }
        temp->next = NULL;
        return head;
    }
    
    用尾插法创建无头结点的单链表
    //尾插法无头结点创建
    
    LNode * Createrail2(int length)
    {
        int data[12] ={0,1,2,3,4,5,6,7,8,9,10,11};
        LNode *p;
        //srand(time(0));
        if(length<1)
            return NULL;
        LNode *first = (LNode*)malloc(sizeof(LNode));
        first->next = NULL;
        first->data = data[0];
        LNode * temp = first;
        int i =1;
        while(i<length)
        {
            p = (LNode*)malloc(sizeof(LNode));
            //p->data = rand()%100+1;
            p->data = data[i];
            temp->next =p;
            temp = p;
            i++;
        }
        temp->next = NULL;
        return first;
    }
    

    打印输出代码

    void PrintL(List L)
    {
        List p = L->next;  //当测试带头结点的单链表,采用这句;
        //List p = L;     //当测试无头结点的单链表,采用这句;
        if(!p)
        {
            return;
        }
        while(p)
        {
            printf("%d  ",p->data);
            p = p->next;
        }
    }
    
    展开全文
  • Josephus问题描述 : 设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m人出列、然后从出列一个人开始重新报数,数到第m人又出列,如此反复直到所有人全部出列为止。要求:对于任意给定n、s、m...
    Josephus问题描述 :
         设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列、然后从出列的下一个人开始重新报数,数到第m的人又出列,如此反复直到所有人全部出列为止。

    要求:对于任意给定的n、s、m,求出按出列次序得到的n个人员的序列。


    /* 上机题1 - 单链表实现Josephus问题 */
    #include <iostream>
    #include <malloc.h>
    using namespace std;
    
    //单链表的结点定义
    template <typename T>       //单链表的节点类 
    class link
    {
    public:
     T data;            //结点数据域 
     link<T> *next;     //结点指针域 
     link(const T d, const link<T> *next_value = NULL)               //link - 含参构造函数 ,const 保证传入的参数2不会被修改
     {
      data = d;
    next = (link<T>*)next_value;      //(link<T>*)强制类型转换,因为next为(link<T>*)类型,但next_value为(const link<T>*)类型
     }                      
    };
    
    //单链表类型定义
    template <typename T>
    class ListJose
    {
     private:
      link<T> *h, *t, *p;              //指向头、尾、当前节点的指针
      int n, s, m;                     // n - 总人数、s - 从第s个人开始、 m - 报数间隔
      
     public:
         ListJose();                     //游戏初始化
      
      ~ListJose();                    //释放链表空间
      
      void play();                    //游戏实际过程算法
      
      void disp();                    //展示初始化后序列顺序 
    };
    
    //游戏初始化 
    template <typename T>
    ListJose<T>::ListJose()
    {
     cout << "请输入参与Josephus游戏的人数:";
        cin >> n;
     cout << "请输入游戏从第几个人开始(编号):" ;
     cin >> s;
     cout << "请输入游戏间隔:" ;
     cin >> m;
     
     //根据输入的总人数(n)创建链表 
     int i = 1;
     while( i <= n )
        {
         if( i == 1 )                      //头节点单独考虑 
         {
          p = new link<T>(i);           // new、delete - 为运算符、所以不包含malloc.h头文件 
          h = p;                       // 但是 malloc() 和 free() - 库函数,得包含malloc.h头文件 
          t = p;
      }
      else                     //非头节点 
      {
       p = new link<T>(i);
       t->next = p;
       t = p;
      }
      
      i++;
     }
    } 
    //析构函数 - 当 头指针(h)不在作用域时,自动销毁释放 
    template <typename T>
    ListJose<T>::~ListJose()
    {
     link<T> *tmp;
     
     while( h != NULL )
     {
      tmp = h;
      h = h->next;
      delete tmp;
     }
     cout << "成功释放链表空间" << endl;
    }
    //输出链表所有节点数据函数 
    template <typename T>
    void ListJose<T>::disp()
    {
     p = h;
     while( p != NULL )
     {
      cout << p->data << " ";
      p = p->next;
     }
    }
    
    //Josephus问题求解的 - 核心算法 
    //这里采用 - 报数到游戏间隔(m)时就直接输出此时编号,不再另设存储空间来保存输出编号信息
    template <typename T>
    void ListJose<T>::play()
    {
     int count = 0, k = 0;                          
     int num = 0;
        p = h;
     for( int i = 1; i < s; i++ )                                           // p 为指向报数起始位置的指针
     {
      p = p->next;                                                        // p 也再接下来的循环中充当着始终指向当前节点的指针
     }
     
     while( count < n )                                                 // count 为出序列人数循环计数变量,当count==n(总人数)时,循环结束
     {
      if( p->data != 0 ) k++;                                      // k 为报数间隔计数变量,k==m(报数间隔), 则k清0,重新计数
      
      if( k == m )
      {
       cout << p->data << " ";
       count++;
       p->data = 0;                                                          // 标记出序列的节点
       k = 0;
      }
      
      p = p->next;                                                  // 循环后移
      if( p == NULL ) p = h;                              // 当 p == t->next(尾节点的next指针), 这超出循环范围,( p = h )重新开始
     }
    }
    
    //主函数  
    int main()
    {
     ListJose<int> A;                  //类模板的实例化 、 <int>指定 template <typename T>中的T为int 
     
     cout << "游戏开始时顺序:";
     A.disp() ;
     cout << endl;
     cout << endl;
     
     cout << "Josephus问题结果:";
     A.play() ;
     cout << endl;
     cout << endl;
     
     return 0; 
    }


    以上代码都通过Dev - C++5.11版本编译运行通过,若有错误,欢迎同行者指出错误,相互学习。

    展开全文
  • 带头非递增无序单链表删除重复节点 (保留第一个节点,删除后续重复节点) 如[1,3,4,1,2,1]执行操作后变为...对于不带头节点的单链表,此处改为 p=head 即可。 while(p != NULL) // p用于遍历链表 { q = p; whi

    带头非递增无序单链表删除重复节点 (保留第一个节点,删除后续重复节点)

    如[1,3,4,1,2,1]执行操作后变为[1,3,4,2]

    
    // 非递归实现  时间复杂度为O(n²)
    void Delete(LNODE *L)
    {
        NODE *p,*q,*r;
        p = L->next; // p指针指向L单链表第一个有数据信息的节点(头节点的下一个节点)
        while(p != NULL)    // p为每一趟要比较的节点
            {
            q = p; //用q遍历
            while(q->next != NULL) // q遍历p后面的结点,并与p数值比较
            {
                if(q->next->data == p->data)
                {
                    r = q->next; // r保存需要删掉的结点
                    q->next = r->next;   // 需要删掉的结点的前后结点相接
                    free(r);
                }
                else
                    q = q->next; //若与p指针所指的节点不相等,继续往后遍历
            }
            p = p->next;//第一个节点与链表所有节点比较结束,指向下一个节点继续遍历比较后继节点
        }
        
    }
    
    
    
    展开全文
  • 如果两个链表最后一个节点的地址相等,则至少有一个链表结点是相互重合的。但是这种方法能确定交点,只能去确定是否有交点。 2.对于两个链表,可以用一种对齐的方法然后再逐项对比。一直遇到相等的一个链表结点,...
  • 不带头节点的单链表1、操作实现1.1单链表的定义1.2初始化单链表1.3得到单链表表长1.4单链表的判空操作1.5建立单链表1.5.1头插法1.5.2尾插法1.6按值查找结点1.6.1得到一个结点1.6.2得到该结点的位置1.7按位查找结点...
  • NODE *delSame_2(NODE *head) { NODE *p,*q,*r; p = head-&...对于不带头节点的单链表,此处改为 p=head 即可。 while(p != NULL) // p用于遍历链表 { q = p; while(q-&gt;next != N...
  • 删除链表中重复结点 题目描述在一个排序链表...5写链表中我们知道对于单链表访问最大缺点就是只能单向,从前向后,所以我们删除也是一样,删除当前就得知道当前一个节点,那么我们这里采用指针记录方式...
  • 2.带头节点的单链表不带头节点的单链 不带头结点的单链表对于一个节点的操作与其他节点不一样,需要特殊处理,所以处理起来应该是更复杂的。因此,通常在单链表的开始结点之前附设一个头结点。(这里主要讲带头...
  • 1、不带头结点的单链表对于一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂性和出现bug的机会,因此,通常 在单链表的开始结点之前附设一个头结点。 2、带头结点的单链表,初始时一定返回的是...
  • 单链表创建

    2016-03-12 10:58:54
    1、不带头结点的单链表对于一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂度和出现bu的机会,通常设置头结点 2、带头结点的单链表,初始化时一定返回的是指向头结点的地址,所以要用二级...
  • 在实现链表操作时,有两种方法去实现:种是带头结点种是不带头结点,即只有头指针情况。 针对于第种: 这种情况下,头指针是指向头结点,而头结点才指向我们首结点,即真正我们要插入结点。 头...
  • 基于单链表的快排

    2016-10-25 00:24:54
    最近要交高级语言程序设计作业,由于满足于插入排序低效率,便顺手撸了一个基于单链表的快排。 虽然网络上已经有很多这样博客了,不过还是贴上来吧,毕竟自己敲模板用起来最顺手是吧= =。嘛,这个函数默认...
  • 不带头结点的单链表,即单链表的第一个结点就存储数据,头指针也指向第一个结点;带头结点的单链表,第一个结点是头结点,不存储数据,从头结点的 next 开始存储,头指针可以从头结点的 next 开始遍历。 对于结点的...
  • 先讲一下对于带头节点的动态链式实现,不带头节点版本请点击这里 代码如下:(C++) myqueue.h #include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; struct Node {  char data;  Node* next...
  • 头结点、头指针 带头结点和不带头结点 优势1:第1个位置插入删除更加方便 优势2:统一空表和非空表处理 ...创建一个单链表 //下面是尾插法建立 //声明节点结构 typedef struct Link{ int elem;//存储整形元素
  •     单向链表(单链表)时链表的一种,它由节点组成,每个节点都包含下一个节点的指针。     单链表的特点是:节点的链接方向是单向的;相对于数组来说,单链表的的随机访问速度较慢,但是单链表删除/添加...
  • 单链表单链表的建立单链表的测长单链表的打印单链表删除结点单链表插入结点单链表排序我把问题看得太复杂了,用了太多的指针,而且排序的时候还交换了节点。...对于不带头节点的链表 使用3指针p1
  • 1、不带头结点的单链表对于一个节点的操作与其他节点不一样,需要特殊处理,这增加了程序的复杂性和出现bug的机会,因此,通常在单链表的开始结点之前附设一个头结点。 2、带头结点的单链表,初始时一定返回的是...
  • 带头节点:使链表插入和删除第一个元素更加方便,统一空表和非空表处理 若使用头结点,无论链表表是否为空,头指针都指向头结点,也就是LNode类型,对于空表和非空表操作是一致。 若使用头结点,当表非空时,...
  • 简单线性链表的是否带头结点...//1、 不带头结点的单链表对于一个节点的操作与其他节点不一样,需要特殊处理, // 这增加了程序的复杂性和出现bug的机会,因此,通常 // 在单链表的开始结点之前附设一个头结点。 //
  • 单链表:一个序列中只含有指向后继结点的连接。...//不带头结点的单链表的初始化 void LinkedListInit1(LinkedList L) { L=NULL; } //带头结点的单链表的初始化 void LinkedListInit2(LinkedList L) ...
  • 1.单链表的逆置, 注意是不带头节点的单链表。 给定单链表1→2→3→4→5 返回被反转后的链表 5→4→3→2→1; 对于逆置单链表来说,如果题目没有做特殊说明,我们可以将链表中的数据进行拷贝,然后将顺序倒置后的...
  • 我们知道单链表对于最后一个元素的删除和插入是很方便的,需要一直遍历到最后一个元素才行,而双向循环链表只需要找到,头节点的一个元素的地址即可 双向循环链表中每一个元素块都有两个指针prev和next,prev...
  • 数据结构(C++)有关练习题

    热门讨论 2008-01-02 11:27:18
    b. 创建一个班机链表,每个节点都包含指向一个乘客链表指针; c. 该程序要有顾客购票,查询班机起飞降落时间,班机订票情况等3个功能,并实现菜单选项 5、 用C++编写一个简单行编辑器,每个结点保存一...

空空如也

空空如也

1 2
收藏数 25
精华内容 10
关键字:

对于一个不带头节点的单链表