zoukankan      html  css  js  c++  java
  • 数据结构 -- 链表&双向链表

           链表是一种物理存储单元非连续非顺序存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。


           使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表双向链表以及循环链表等。


           相较之于单链表,双向链表在查找前驱节点时更为方便,而单向链表却需要遍历查找;而相较之于双向链表,单链表在更加节省内存空间(双向链表比单链表多定义了一个指向前驱结点的指针)。


            以下为关于单链表以及双向链表的c++实现方法:



            1. 单链表


    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    typedef struct linkTable{
    	int info;
    	linkTable *next;
    };
    
    //创建链表
    
    linkTable* createLinkTable(linkTable *node)
    {
    	int temp = 0;
    	linkTable *head = NULL;
    	linkTable *p = (linkTable*)malloc(sizeof(linkTable));
    	while (1)
    	{
    		scanf("%d",&temp);
    		if (temp != -9999)
    		{
    			if (head == NULL)
    			{
    				p->info = temp;
    				p->next = NULL;
    				head = p;
    			}else{
    				linkTable *newnode = (linkTable *)malloc(sizeof(linkTable));
    				newnode->info = temp;
    				newnode->next = NULL;
    				p->next = newnode;
    				p = p->next;
    			}
    		}else{
    			break;
    		}
    	}
    	return head;
    
    }
    
    //在链表头部插入节点
    
    linkTable* insertToHead(linkTable *node , int val)
    {
    	linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    	scanf("%d",newnode->info);
    	newnode->next = node;
    	return newnode;
    }
    
    //在链表中间插入节点
    
    void insertToMid(linkTable *node , int val , int pos)
    {
    	int count = 0;
    	linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    	newnode->info = val;
    	while (node->next != NULL && ++count < pos-1)
    	{
    		node = node->next;
    	}
    	newnode->next = node->next;
    	node->next = newnode;
    	return;
    }
    
    //插入尾部节点
    
    void insertToTail(linkTable *node , int val)
    {
    	linkTable *newnode = (linkTable*)malloc(sizeof(linkTable));
    	newnode->info = val;
    	newnode->next = NULL;
    	while (node->next != 0)
    	{
    		node = node->next;
    	}
    	node->next = newnode;
    	return;
    }
    
    //显示所有节点数值
    
    void display(linkTable *node)
    {
    	while (node != NULL)
    	{
    		printf("%d ",node->info);
    		node = node->next;
    	}
    	return;
    }
    
    //删除起始节点
    
    linkTable* deleteHead(linkTable *node)
    {
    	linkTable *tempNode = (linkTable*)malloc(sizeof(linkTable));
    	tempNode = node;
    	node = node->next;
    	free(tempNode);
    	return node;
    }
    
    //删除尾部节点
    
    void deleteTail(linkTable *node)
    {
    	linkTable *tempNode = (linkTable*)malloc(sizeof(linkTable));
    	while (node->next->next != NULL && node->next != NULL)
    	{
    		node = node->next;
    	}
    	tempNode = node->next;
    	node->next = NULL;
    	free(tempNode);
    	return;
    }
    
    //搜索指定节点,并返回节点
    
    linkTable* searchNode(linkTable *node , int val)
    {
    	while (node->info != val)
    	{
    		if (node == NULL)
    		{
    			printf("No element ! 
    ");
    			return NULL;
    		}
    		node = node->next;
    	}
    	return node;
    }
    
    int main(void)
    {
    	linkTable *node = (linkTable*)malloc(sizeof(linkTable));
    	node = createLinkTable(node);
    	display(node);
    	return 0;
    }
    


             2. 双向链表


    #include <cstdio>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    
    using namespace std;
    
    typedef struct DLinkList{
    	int info;
    	DLinkList *prev;
    	DLinkList *next;
    };
    
    //链表的创建
    
    DLinkList* createDLT(void)
    {
    	int temp = 0;
    	DLinkList *p = (DLinkList*)malloc(sizeof(DLinkList));
    	DLinkList *head = NULL;
    	while (1)
    	{
    		scanf("%d",&temp);
    		if (temp != -9999)
    		{
    			if (head == NULL)
    			{
    				head = (DLinkList*)malloc(sizeof(DLinkList));
    				p->info = temp;
    				p->next = NULL;
    				p->prev = NULL;
    				head = p;
    			}else{
    				DLinkList *newnode = (DLinkList*)malloc(sizeof(DLinkList));
    				newnode->info = temp;
    				newnode->prev = p;
    				newnode->next = NULL;
    				p->next = newnode;
    				p = p->next;
    			}
    		}else{
    			break;
    		}
    	}
    	return head;
    }
    
    //链表的遍历输出
    
    void display(DLinkList *node)
    {
    	while (node != NULL)
    	{
    		printf("%d  ",node->info);
    		node = node->next;
    	}
    	return;
    }
    
    //添加链表头节点
    
    DLinkList* insert_Head(DLinkList *node , int val)
    {
    	DLinkList *newnode = (DLinkList*)malloc(sizeof(DLinkList));
    	newnode->info = val;
    	newnode->next = node;
    	newnode->prev = NULL;
    	node->prev = newnode;
    	return newnode;
    }
    
    //删除链表某位置元素
    
    void delete_Elem(DLinkList *node , int n)
    {
    	int count = 1;
    	while (count < n && node != NULL)
    	{
    		node = node->next;
    		count++;
    	}
    	if (node != NULL)
    	{
    		if (node->next != NULL)
    		{
    			node->prev->next = node->next;
    			node->next->prev = node->prev;
    		}else{
    			node->prev->next = NULL;
    		}
    	}
    	return;
    }
    
    int main(void)
    {
    	DLinkList *node = (DLinkList*)malloc(sizeof(DLinkList));
    	node = createDLT();
    	node = insert_Head(node,9);
    	delete_Elem(node,2);
    	display(node);
    	return 0;
    }


  • 相关阅读:
    用vue ui创建的项目怎么关闭eslint校验
    SQL修改表约束实现
    获取微信公众号的粉丝openid以及用openid获取unionID
    怎么停掉或关闭运行的npm run dev
    .NET解密得到UnionID
    微信获取信息发生错误(两个access_token的区别),错误代码:40001,说明:invalid credential, access_token is invalid or not latest hints
    微信获取不了用户头像等信息
    微信sdk上传图片大小1k,损坏的问题以及微信上传图片需要的配置
    微信订阅号中获取openid以及个人信息
    Bootstrap中宽度大于指定宽度时有空白的解决方法
  • 原文地址:https://www.cnblogs.com/csnd/p/12897064.html
Copyright © 2011-2022 走看看