精华内容
下载资源
问答
  • 循环链表(循环单链表和双链表

    千次阅读 2021-02-04 13:52:36
    循环链表前言一、循环单链表的初始化二、判断是否为空或表尾结点三、循环双链表的初始化四、循环双链表的插入与删除 前言 对于循环单链表而言,在进行插入删除时,可以让指针指向尾部,对于表头(通过尾部找到头部...


    前言

    对于循环单链表而言,在进行插入和删除时,可以让指针指向尾部,对于表头(通过尾部找到头部)和表尾的操作的时间复杂度均为O(1);


    一、循环单链表的初始化

    //带头结点的循环单链表
    typedef struct LNode{
    	ElemType data;
    	struct LNode *next;
    }LNode,*Linklist;
    bool Initlist(Linklist &L){
    	L=(LNode *)malloc(sizeof(LNode));	//分配一个头结点,且不存储任何数据
    	if(L==NULL)
    		return false;	//内存不足,分配失败
    	L->next=L;	//区别于单链表的初始化,头结点的next指向头结点
    	return ture;	
    }
    
    

    二、判断是否为空或表尾结点

    //判断循环单或双链表是否为空
    bool Empty(Linklist L){
    	return(L->next==L);
    }
    
    //判断结点p是否是循环单或双链表的表尾结点
    bool isTail(Linklist L,LNode *p){
    	return(p->next==L);
    }
    
    

    三、循环双链表的初始化

    //初始化循环双链表
    bool InitDLinklist(DLinklist &L){
    	L=(DLNode *)malloc(sizeof(DLNode));	//分配一个头结点,且不存储任何数据
    	if(L==NULL)
    		return false;	//内存不足,分配失败
    	L->prior=L;	//区别于循环单链表的初始化,头结点的prior指向头结点
    	L->next=L;	
    	return ture;	
    }
    
    

    四、循环双链表的插入与删除

    //循环双链表的插入
    bool InsertNextDNode(DNode *p,DNode *s){
    	s->next=p->next;
    	p->next->prior=s;
    	s->prior=p;
    	p->next=s;
    }
    
    //循环双链表的删除
    bool DeleteDNode(DNode *p){
    	p->next=q->next;
    	q->next->prior=p;
    	free(q);
    }
    
    
    
    展开全文
  • 链表不仅作为链式存储的一种实现方式,还表达了计算机不连续(离散)的存储思想。

    链表不仅作为链式存储的一种实现方式,还表达了计算机不连续(离散)的存储思想在初学阶段,链表的实现类型有单链表(带/不带头结点)、循环单链表、双链表、循环双链表四种。

    上文已经讲解了单链表,接下来将讲解其他三类。


    Table of Contents

    循环单链表

    双链表

    循环双链表


    循环单链表

     

    定义:

    将单链表中终端结点的指针端由 NULL 改为 指向头结点 ,就使整个单链表形成一个,这种头尾相接的单链表称为单循环链表,简称循环链表

     

     

    两种情形:

    • 为使空链表与非空链表处理一致,通常设置一个头结点。但并非必须设置头结点。

    循环单链表特征:

    1. 对于单链表而言,最后一个结点指向NULL;把最后一个结点的不指向NULL而指向头,就是循环单链表;
    2. 在单循环链表上的操作基本上与非循环链表相同。循环链表和单链表的主要差异就在于循环的条件判断上,原来是 p->next == NULL,现在是 p->next != 头结点 ,则循环未结束。
    3. 单循环链表可以从表中任意结点开始遍历整个链表,不仅如此,有时对链表常做的操作是在表尾、表头进行。如果头指针表示循环链表,则需O(n) 时间找到最后一个结点。若改尾指针表示循环链表,此时查找开始结点和终端结点都很方便了查找终端结点时间是O(1),而开始结点,其实就是 rear->next->next ,其时间复杂也为O(1)。

    第一个循环单链表

    
    #include <stdio.h>
    #include <malloc.h>
    #include <assert.h>
    
    typedef struct node
    {
    	int data;
    	struct node* next;
    }Node; //struct node 完全等于 Node(结构体变量)
    typedef Node* LinkList; //struct node * 完全等于 LinkList(结构体指针)
    
    int main()
    {
    	LinkList head = (LinkList)malloc(sizeof(Node));
    	assert(head != NULL);  //检查malloc之后是不是空间不够,返回了空指针NULL(WarningC6011:取消对NULL指针的引用)
    	LinkList NodeAa = (LinkList)malloc(sizeof(Node));
    	assert(NodeAa != NULL);
    	LinkList NodeBb = (LinkList)malloc(sizeof(Node));
    	assert(NodeBb != NULL);
    	LinkList NodeCc = (LinkList)malloc(sizeof(Node));
    	assert(NodeCc != NULL);
    
    	head->data = NULL; //头结点,不保存数据
    	head->next = NodeAa;
    	NodeAa->data = 202;
    	NodeAa->next = NodeBb;
    	NodeBb->data = 303;
    	NodeBb->next = NodeCc;
    	NodeCc->data = 404;
    	NodeCc->next = head;  //单链表中:NodeCc->next = NULL;
    
    	LinkList p = head->next; //把链表头结点的下一个节点,交给指针p,去遍历
    	while (p != head)
    	{
    		printf("%d  ", p->data);
    		p = p->next;
    	}
    
    	return 0;
    }
    

     

     


    双链表

     

    定义:

    双向链表也叫双链表,它的每个数据结点中都有两个指针(保存两个节点的地址),分别指向直接后继直接前驱

     

     

    双链表的代码定义:

     

    typedef struct node
    {
    	int data;
    	struct node* pre; //前驱
    	struct node* next; //后继
    }Node;
    

     

    特性:

    1. 从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点
    2. 循环链表的最后一个结点指向头结点,循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。
    3. 双向链表使单链表中扩展出来的结构,因此有一部分操作与单链表是相同的,如求长度函数、查找元素位置、打印函数、销毁函数等,这些函数操作都只要涉及一个方向的指针即可。

    第一个双链表

    第一个双链表
    #include <stdio.h>
    #include <malloc.h>
    #include <assert.h>
    
    typedef struct node
    {
    	int data;
    	struct node* pre;
    	struct node* next;
    }Node; //struct node 完全等于 Node(结构体变量)
    typedef Node* LinkList; //struct node * 完全等于 LinkList(结构体指针)
    
    int main()
    {
    	LinkList head = (LinkList)malloc(sizeof(Node));
    	assert(head != NULL);  //检查malloc之后是不是空间不够,返回了空指针NULL(WarningC6011:取消对NULL指针的引用)
    	LinkList NodeAa = (LinkList)malloc(sizeof(Node));
    	assert(NodeAa != NULL);
    	LinkList NodeBb = (LinkList)malloc(sizeof(Node));
    	assert(NodeBb != NULL);
    	LinkList NodeCc = (LinkList)malloc(sizeof(Node));
    	assert(NodeCc != NULL);
    
    	head->data = 101;
    	head->pre = NULL;
    	head->next = NodeAa;
    
    	NodeAa->data = 202;
    	NodeAa->pre = head;
    	NodeAa->next = NodeBb;
    
    	NodeBb->data = 303;
    	NodeBb->pre = NodeAa;
    	NodeBb->next = NodeCc;
    
    	NodeCc->data = 404;
    	NodeCc->pre = NodeBb;
    	NodeCc->next = NULL;  //单链表中:NodeCc->next = NULL;
    
    	LinkList p = head; //把链表头结点的下一个交给指针p,去遍历
    	printf("顺序遍历:");
    	while (p != NULL)
    	{
    		printf("%d  ", p->data);
    		p = p->next;
    	}
    
    	printf("\n逆序遍历:");
    	LinkList tail = NodeCc;
    	p = tail;
    	while (p != NULL)
    	{
    		printf("%d  ", p->data);
    		p = p->pre;
    	}
    
    	return 0;
    }

     

     


    循环双链表

     

    定义:

    双向链表也叫双链表,它的每个数据结点中都有两个指针(保存两个节点的地址),分别指向直接后继直接前驱头指针的前驱指向最后一个节点,最后一个节点的后继指向头指针。

    双链表的代码定义:

    typedef struct node
    {
    	int data;
    	struct node* pre; //前驱
    	struct node* next; //后继
    }Node;
    

    特性:

    1. 从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点
    2. 循环链表的最后一个结点指向头结点,循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。
    3. 双向链表使单链表中扩展出来的结构,因此有一部分操作与单链表是相同的,如求长度函数、查找元素位置、打印函数、销毁函数等,这些函数操作都只要涉及一个方向的指针即可。

    两种情形:

    第一个循环双链表

    #include <stdio.h>
    #include <malloc.h>
    #include <assert.h>
    
    typedef struct node
    {
    	int data;
    	struct node* pre;
    	struct node* next;
    }Node; //struct node 完全等于 Node(结构体变量)
    typedef Node* LinkList; //struct node * 完全等于 LinkList(结构体指针)
    
    int main()
    {
    	LinkList head = (LinkList)malloc(sizeof(Node));
    	assert(head != NULL);  //检查malloc之后是不是空间不够,返回了空指针NULL(WarningC6011:取消对NULL指针的引用)
    	LinkList NodeAa = (LinkList)malloc(sizeof(Node));
    	assert(NodeAa != NULL);
    	LinkList NodeBb = (LinkList)malloc(sizeof(Node));
    	assert(NodeBb != NULL);
    	LinkList NodeCc = (LinkList)malloc(sizeof(Node));
    	assert(NodeCc != NULL);
    
    	head->data = NULL; //头结点,不保存数据
    	head->pre = NodeCc;
    	head->next = NodeAa;
    
    	NodeAa->data = 202;
    	NodeAa->pre = head;
    	NodeAa->next = NodeBb;
    
    	NodeBb->data = 303;
    	NodeBb->pre = NodeAa;
    	NodeBb->next = NodeCc;
    
    	NodeCc->data = 404;
    	NodeCc->pre = NodeBb;
    	NodeCc->next = head;  //单链表中:NodeCc->next = NULL;
    
    	LinkList p = head->next; //把链表头结点的下一个交给指针p,去遍历
    	printf("顺序遍历:");
    	while (p != head)
    	{
    		printf("%d  ", p->data);
    		p = p->next;
    	}
    
    	printf("\n逆序遍历:");
    	p = p->pre;
    	while (p != head)
    	{
    		printf("%d  ", p->data);
    		p = p->pre;
    	}
    
    	return 0;
    }
    


     

    展开全文
  • 双链表:拥有指向上一节点下一节点的指针。相对于单链表,在找当前节点的前一节点时比较方便,占用空间比单链表大。 单循环链表:单链表中,从一已知结点出发,只能访问到该结点及其后续结点,无法找到该结点之前...

    单链表:拥有指向下一节点的指针。查找元素需要从头结点遍历

    双链表:拥有指向上一节点和下一节点的指针。相对于单链表,在找当前节点的前一节点时比较方便,占用空间比单链表大。

    单循环链表:单链表中,从一已知结点出发,只能访问到该结点及其后续结点,无法找到该结点之前的其它结点。而在单循环链表中,从任一结点出发都可访问到表中所有结点,这一优点使某些运算在单循环链表上易于实现。

    双循环链表:可以从任何结点开始任意向前向后双向访问。

    单链表和单循环链表:只能在当前结点后插入和删除。


    双链表:可以在当前结点前面或者后面插入,可以删除前趋和后继(包括结点自己)。


    存储:单链表和单循环链表存储密度大于双链表。

    哈希表:在哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下,仅需一次定位即可完成,时间复杂度为O(1)。我们要新增或查找某个元素,我们通过把当前元素的关键字 通过某个函数映射到数组中的某个位置,通过数组下标一次定位就可完成操作。

            存储位置 = f(关键字)

      其中,这个函数f一般称为哈希函数,这个函数的设计好坏会直接影响到哈希表的优劣。例如:

            

    当我们对某个元素进行哈希运算,得到一个存储地址,然后要进行插入的时候,发现已经被其他元素占用了,其实这就是所谓的哈希冲突,也叫哈希碰撞。数组是一块连续的固定长度的内存空间,再好的哈希函数也不能保证得到的存储地址绝对不发生冲突。哈希冲突的解决方案有多种:开放定址法(发生冲突,继续寻找下一块未被占用的存储地址),再散列函数法,链地址法,而HashMap即是采用了链地址法,也就是数组+链表的方式,

    hashmap:简单来说,HashMap由数组+链表组成的,数组是HashMap的主体链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表(当前entry的next指向null),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度为O(n),首先遍历链表,存在即覆盖,否则新增;对于查找操作来讲,仍需遍历链表,然后通过key对象的equals方法逐一比对查找。所以,性能考虑,HashMap中的链表出现越少,性能才会越好。

    展开全文
  • 单链表双链表循环链表

    千次阅读 2019-09-20 20:39:18
    这学期的数据结构课有讲到链表,所以再来温故一下,毕竟温故知新嘛。 链表与数组的区别 链表和数组都是线性表,两者区别如下: 数组静态分配内存,链表动态分配内存;更进一步说就是数组不易拓展,但链表易...

    这学期的数据结构课有讲到链表,所以再来温故一下,毕竟温故知新嘛。

    链表与数组的区别

    链表和数组都是线性表,两者区别如下:

    • 数组静态分配内存,链表动态分配内存;更进一步说就是数组不易拓展,但链表易拓展。
    • 数组在内存中连续,链表不连续;更进一步说就是数组可能会造成内存浪费,但链表的内存利用率高;
    • 数组利用下标定位元素,时间复杂度为O(1),链表在最坏情况下是O(n);即在随机性查找上数组比链表更快。
    • 在数组中进行插入和删除操作的时间是O(n),链表是O(1)。

    单链表

    单链表接触的太多了,单链表中每一个结点由数据域和指针域构成,因为C语言有指针的概念,可以很方便的控制内存,因此大多数关于链表的实现代码都是C/C++版本的,其它语言则大多都是模拟链表,但其实Python也可以实现真实链表,尽管Python不能直接操作内存,但因为Python是动态语言,因此可以直接把对象赋值给新的变量而不需要预先定义。

    这篇博客仍以C语言来实现链表,Python版本感兴趣的可以自己尝试。

    链表其实就是一个又一个的结点连接而成,这很好理解,如果你的指针学的还不错的话,那么创建一个链表并不是一件难事。

    创建结点:

    typedef struct Node{
        int data;
        struct Node *next;
    }*Linklist;   
    

    创建链表:

    Linklist createList(int n)
    {
        Linklist p,q,head;
        head = (Linklist)malloc(sizeof(Linklist));
        q = head;
        for(int i = 0; i < n; i++)
        {
            p = (Linklist)malloc(sizeof(Linklist));
            scanf("%d",&p->data);
            p->next = NULL;
            q->next = p;
            q = p;
        }
        return head;
    }
    

    输出链表:

    void print(Linklist head)
    {
    	  Linklist p = head->next;
    	  while(p)
    	  {
               printf("%d ",p->data);
               p = p->next;
    	}
    }
    

    修改结点:

    void changeList(Linklist head,int pos,int x)//修改第pos位的结点,修改值为x
    {
        Linklist p = head;
        int i = 0;
        while(i < pos && p != NULL)
        {
            p = p->next;
            i++;
        }
        if(p)
            p->data = x;
        else
            printf("结点不存在!\n");
    }
    

    插入结点:

    void insertList(Linklist head,int pos,int x)
    {
    	  Linklist p = head;
    	  int i = 0;
    	  while(i < pos - 1 && p != NULL) //遍历到pos位置的前驱结点
    	  {
    		  p = p->next;
    		  i++;
    	  }
    	  Linklist newnode = (Linklist)malloc(sizeof(Linklist));
    	  newnode->data = x;
    	  newnode->next = p->next; //先后插
    	  p->next = newnode; //再前插
    }
    

    删除结点(按位置删):

    void deleteList(Linklist head,int pos)
    {
    	  Linklist p = head; //记录前驱
    	  Linklist q = head->next; //记录当前结点
    	  int i = 0;
    	  while(i < pos - 1 && p != NULL) //遍历到pos位置
    	  {
    	      p = p->next;
    		  q = q->next;
    		  i++;
    	  }
    	  p->next = q->next; //前驱结点指向待删结点的后继结点,即把待删结点隔离出来
    	  free(q); //删除
    	  q->next = NULL; //结点指向空
    }
    

    关于单链表的基本操作基本上也就上面那些,其中一些简单的细节被我省略了,比如在插入或者删除之前判断pos是否是不合理的值等,这些都比较好写,也就不再说,另外,因为如果每一个操作都详细辅以文字说明的话篇幅太长,所以大部分情况下我都直接给出了代码并附上少量的关键性注释,目的只是起到一个快速浏览和记忆的作用,因此这篇博客不太适合刚入门的新手,适合学过但记忆的不太牢固的人拿来复习。

    双链表

    单链表因为每一个结点只保存next的缘故,在它中只能通过一个结点访问它的后继结点而无法访问前驱,如果你想要通过一个结点既能访问前驱又能访问后继,那么可以使用双链表。

    双链表与单链表在结构上唯一的不同在于,构成双链表的每一个结点,除了数据域和指向后继的next域之外,新添了一个指向前驱的pre域。在双链表中,查找或者插入等操作不仅可以从链表的头部开始,也可以从尾部开始。仿照创建单链表的思路,在创建双链表时,我们将创建两个哑元结点,分别代表双链表的head和tail。head以及tail结点都不保存数据,head结点的pre域为空,tail结点的next域为空。

    双链表看起来是高大上了不少,但对于插入、查找等大部分操作,单链表和双链表在最坏情况下的时间损耗其实是相同的,均为O(n)。双链表更重要的作用是用在散列表中,在采用了双链表的散列表中,删除操作具有O(1)的时间复杂度,因为删除操作不仅需要找到待删结点的前驱还需要找到它的后继,在单链表中只能找到后继,但在双链表中,前驱和后继都可以同时找到。

    创建结点:

    typedef struct Node{
        int data;
        struct Node *pre,*next;
    }*Linklist;
    

    创建链表:

    Linklist head = (Linklist)malloc(sizeof(Linklist));
    Linklist tail = (Linklist)malloc(sizeof(Linklist));
    void createList(int n)
    {
    	  Linklist p,q;
    	  head->pre = head->next = NULL;
    	  tail->pre = tail->next = NULL;
    	  q = head;
    	  for(int i = 0; i < n; i++)
    	  {
    		  p = (Linklist)malloc(sizeof(Linklist));
    		  scanf("%d",&p->data);
    		  p->next = NULL;
    		  p->pre = q;
    		  q->next = p;
    		  q = p;
    	  }
    	  p->next = tail;
    	  tail->pre = p;
    }
    

    输出链表:

    void next_print(Linklist head) //正向输出
    {
    	  Linklist p = head->next;
    	  while(p && p != tail)
    	  {
              printf("%d ",p->data);
              p = p->next;
    	  }
    	  printf("\n");
      }
    
    void pre_print(Linklist tail) //反向输出
    {
    	  Linklist p = tail->pre;
    	  while(p && p != head)
    	  {
              printf("%d ",p->data);
              p = p->pre;
    	  }
    	  printf("\n");
    }
    

    对于查找结点、修改结点、插入结点等等之类,与单链表基本一致,唯一不同的就是双链表可以选择正向遍历或者反向遍历两种方式。

    接下来给出与单链表稍微有些许不同的删除操作:
    删除结点:

    void deleteList(Linklist head,int pos)
    {
          Linklist p = head;
          int i = 0;
          while(i < pos && p != tail) //遍历到当前结点
          {
        	  p = p->next;
          	  i++;
    	  }
    	  p->pre->next = p->next; //前驱指向后继
    	  p->next->pre = p->pre; //后继指向前驱
    	  free(p);
    	  p->next = p->pre = NULL;
    }
    

    循环链表

    将一条链表的首尾相连我们就会得到一条循环链表。在单链表中,将尾结点的next域指向head结点,由此构造出一条单循环链表。在双链表中,将head结点的pre域指向尾结点,尾结点的next域指向head结点,由此构造出一条双循环链表。

    循环链表有什么好处呢?首先,因为是循环结构,因此无须增加存储量,仅对表的连接方式稍作改变,即可使表的处理更加方便灵活。
    ① 循环链表没有NULL指针,因此在值判断操作中就不再是判别p == NULL 或者 p->next == NULL等方式,而是判别它们是否等于某一指针;
    ② 在单链表中实现全遍历只能从head节点开始,在双链表中只能从head或者tail结点开始,而在循环链表中可以从链表的任意位置开始;

    单循环链表

    单循环链表是在单链表的基础上实现的,在这里有两种实现方式,一种是带头结点的单循环链表,一种是带尾结点的单循环链表,两种方式均可实现,但有时候带尾结点的单循环链表可能更为方便。比方说:我们如果要查找链表的首元素和尾元素,那么用带头结点的单循环链表的话分别需要O(1)和O(n)的复杂的,因为虽然首元素可以直接得到,但尾元素却只能遍历得到,而如果采用带尾结点的单循环链表,则时间复杂度均是O(1)。

    本来我是打算附上关于单循环链表一些基本操作的代码实现的,但敲了几个感觉实在是没什么用处,因为这些代码几乎和单链表的完全一样,所以这里我就略去了。

    双循环链表

    嗯。。。没啥需要说的,会写双链表就肯定会写双循环,双循环继承了双链表的许多优势同时又具有循环链表的优势,我就不再重复赘述了。

    令附一表,在各种链表中实现相关基础操作的时间复杂度对比,包括单链表,已排序的单链表,双链表,以及已排序的双链表。
    在这里插入图片描述

    关于链表还有很多值得说的地方,但碍于篇幅这篇就不再介绍了,下一篇再补充吧。

    展开全文
  • 这个资料实现的是循环单链表-双链表,为初学者提供源码
  • 单链表相同,循环单链表也有带头结点不带头结点两种。带头结点的循环单链表实现插入删除操作较为方便,且更加适用。 2. 单链表与循环单链表比较: 循环单链表可以从尾到头,而单链表不能从尾到头。因此处理...
  • 单链表循环链表、双向循环链表总结

    千次阅读 多人点赞 2019-11-23 18:56:31
    链表介绍 不带头结点的单向链表 带头结点的单向链表 循环链表 双向循环链表
  • 单链表、双向链表循环链表

    千次阅读 多人点赞 2019-07-26 14:26:09
    学习三种常见的链表结构,他们分别是:单链表、双向链表和循环链表。 单链表 单链表有两个较特殊节点,头结点和尾节点。头结点用来记录链表的基地址,可以用来遍历整条链表。尾结点的指针不是指向下一个节点而是指向...
  • 单链表的定义及基本操作 #include<iostream>...//node * pnode 等价,在使用中node *强调这是一个结点,pnode 强调这是一个链表 //基本操作——按序号查找节点值 node * GetElem(pnode L,int p
  • 最近在面试过程中总被问到链表的问题,因此这里把自己实现的链表操作上传给大家共享!包括单链表,双链表,循环单链表,循环双链表的(可重复)插入(可重复)删除的完整实现,由c及Code::Blacks实现.
  • 单链表双链表循环链表的区别

    千次阅读 2019-02-18 16:45:06
    单向链表(单链表)  单向链表,它包含两个域,一个信息域一个指针域。这个链接指向表中的下一个节点,而最后一个节点则 指向一个空值NULL。...双向链表,(双链表)  双向链表中不仅有指向...
  • 单链表和双链表的区别

    千次阅读 2019-01-23 18:34:33
    双链表既有指向下一个结点的指针,也有指向上一个结点的指针 二、适用情况不同 单向链表更适合元素的增加与删除 双向链表更适合元素的查询工作 三、读取不同 单链表只能单向读取 双链表可以双向读取 ...
  • 单链表循环链表和双向链表

    千次阅读 2018-05-01 12:26:40
    单链表: 一.单链表与顺序表相比: 1.顺序表可以方便的随机存取表中的任一节点,速度快;...相反,链表则适用于插入删除频繁,表长估计不定的情形。 3.单链表中的逻辑位置连续,物理位置非连续;而顺序...
  • 1.单链表的基本操作(C语言) 创建头节点 Linklist *Creat(Linklist *L) { L = (Linklist *)malloc(sizeof(Linklist)); if (L == NULL) return NULL; /*内存分配不成功,返回空指针*/ L -> next = NULL; ...
  • 总结:以空间换取时间。
  • 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。 原创文章 19获赞 2访问量...
  • 简单理解单链表、双链表、循环单链表循环双链表 单链表只有后继指针 双链表有后继指针前驱指针 循环单链表尾指针指向了头指针 循环双链表头结点的前驱指针指向了尾结点,尾结点的后继指针指向了头结点 ...
  • 循环单链表 #include using namespace std; typedef struct LNode { //循环单链表 int data; struct LNode* next; }LNode, * LinkList; //初始化一个循环单链表 bool InitList(LinkList &L) { LNode *L = new ...
  • 循环单链表和双向链表的建立
  • 文章目录循环链表循环单链表循环双链表静态链表说明 循环链表  循环链表一般包括循环单链表循环双链表,如下图所示: 循环单链表   循环单链表与单链表的区别在于,表中最后一个结点的指针不是NULL,而改为...
  • c/c++ 循环单链表循环双链表

    千次阅读 2018-05-13 16:57:27
    最近遇到了一个作业题目...编写一个算法将此表改为循环双链表。看了一下感觉不难,好,开始动手。建立链表结构 链表在c语言建立是通过结构体建立,通过在结构体内部建立其结构体本身的指针类型指向下一个节点来实现...
  • 1、链表(Linked List)介绍 1.1、内存结构 ...又由于此链表的每个结点中只有一个指向后继的指针,所以称其为单链表或线性链表。下图的单链表是带有头结点的单链表,头结点的作用是方便单链表的特殊操作,简化代
  • 目录1 单链表节点实现单链表操作单链表实现测试链表与顺序表对比2 单向循环链表操作实现测试3 双向链表操作实现测试 1 单链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域...
  • 文档包括带表头单链表的实现,双链表的操作,双链表的冒泡排序,不带表头的单链表,双向链表、链表节点的排序
  • 一、单链表单链表的插入与删除:假设我们有个节点ai,指向他的指针为p,有个节点为e,指向他的指针为s①插入:想要把e插入到ai的后面,只需要把s的next指向p的next,再把p的next指向e就可以了②删除:想要删除ai+1...
  • 内部结点唯一的前驱后继,表头 只有后继,表尾只有前驱。 1、线性结构 ...//线性表类模板如下,是顺序表类和链表类的基类,用虚函数virtual template <class T> //value的类型是T class LinearLi...
  • 数据结构:单链表双链表的区别与实现

    千次阅读 多人点赞 2019-08-05 19:22:10
    四、双向(循环)链表的实现 一、链表 链表所需要的功能: 初始化 创建新节点 插入 删除 查询 链表的销毁(释放包括头结点在内的空间) 链表的清空(释放除了头结点以外的空间) 链表的优缺点: 优点:链表...
  • 单链表 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,852
精华内容 9,540
关键字:

循环单链表和循环双链表