数据结构与算法什么是链表?并用代码手动实现一个单向链表

Posted 逆流°只是风景-bjhxcc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法什么是链表?并用代码手动实现一个单向链表相关的知识,希望对你有一定的参考价值。

文章目录


一、链表是什么

  1. 链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,有一系列结点(地址)组成,结点可动态的生成。

  2. 结点包括两个部分:
    (1)存储数据元素的数据域(内存空间)
    (2)存储指向下一个结点地址的指针域。

  3. 相对于线性表顺序结构,操作复杂。

  4. 链表分为 :
    (1)单链表
    (2)双链表
    (3)单向循环链表
    (4)双向循环链表

二、链表的作用

  1. 实现数据元素的存储按一定顺序储存,允许在任意位置插入和删除结点。

  2. 包括单向结点,双向结点,循环接点。

三、链表与数组的区别

说到链表那肯定要聊一下数组,为什么会出现链表呢?

  1. 数组:使用一块连续的内存空间地址去存放数据,但
    例如:
    int a[5]=1,2,3,4,5 突然我想继续加两个数据进去,但是已经定义好的数组不能往后加,只能通过定义新的数组
    int b[7]=1,2,3,4,5,6,7 这样就相当不方便比较浪费内存资源,对数据的增删不好操作。

  2. 链表:使用多个不连续的内存空间去存储数据, 可以 节省内存资源(只有需要存储数据时,才去划分新的空间),对数据的增删比较方便。

四、如何理解链表

理论的东西我就不说太多了,下面我将以代码+图形的方式让大家很通俗易懂的理解链表。

  1. 单链表的结构体
struct node 

	int data;//存放数据
	struct node  *next; //地址域 (与节点的类型地址相匹配)
	

可以把这个结构体理解成这个样子

  1. 创建链表的新节点
struct node *creat_node(int data)

	struct node  *new = malloc(sizeof(struct node));
	new->data = data; 
	new->next = NULL;
	
	return  new;
		

  1. 插入节点
struct  node* insert_node(struct  node*p,struct  node*new)
	
	 p->next = new;		

  1. 显示链表
void show(struct node  *p)
	
	while(1)
			
		if(p== NULL)  //假设p已经为NULL则返回 
		
			return ;
						
		printf("p=%d\\n",p->data);		
		p  = p->next;  //链表的重要知识点!!! 遍历节点向下走 		
		

有了以上三个步骤我们就可以做出一条简单的单链表。

五、单链表完整代码

list.c

#include  <stdio.h>
#include  <stdlib.h>
//设计链表的节点 
struct node 

	int data;//存放数据
	struct node  *next; //存放地址  (与节点的类型地址相匹配)
	
;

//创建节点 
struct node *creat_node(int data)

	struct node  *new = malloc(sizeof(struct node));
	new->data = data; 
	new->next = NULL;
	return  new;		

 
//插入节点 (链接节点)
struct  node* insert_node(struct  node*p,struct  node*new)
	
	 p->next = new;		


//显示节点数据  (遍历节点)
void show(struct node  *p)
	
	while(1)
			
		if(p== NULL)  //假设p已经为NULL则返回 
		
			return ;
						
		printf("p=%d\\n",p->data);		
		p  = p->next;  //链表的重要知识点!!! 遍历节点向下走 		
		

 
 
int main()

    //1.分配节点空间
	struct node  *a0 = creat_node(100); 
	struct node  *a1 = creat_node(200); 
	struct node  *a2 = creat_node(300);
	
	inser_node(a0,a1);
	inser_node(a1,a2);
	
	//通过a0  访问a0  a1  a2的数据    //3.访问节点中的数据 
	//printf("a0=%d,a1=%d,a2=%d\\n",a0.data,a0.next->data,a0.next->next->data);
	
	show(a0);

算法入门(七,数据结构,单向链表与双链表)

链表结构

什么是链表?

链表是一种物理存储单元上非连续,非顺序的存储结构(数据元素的逻辑顺序是通过链表中的指针链就=接次序实现的)链表由一系列结点组成,结点可以在运行时动态生成。

什么是结点?

结点由二部分组成,一个是存储数据单元的数据域,一个是存储下一个节点的指针(连接区)。

python创建一个元素为节点,使用类改变数据类型。

#定义为结点对象
class Node:
    def __init__(self,val):
        #val存放数据元素
        self.val=val
        #next存放下一个节点的标识符
        self.next=None

链表的作用

链表结构可以充分利用计算机的内部空间,实现灵活的内存动态管理。

链表与顺序表的操作复杂度对比

链表失去了顺序表随机读取的优点,同时链表增加了结点的指针域。空间开销大,但是对存储空间的使用相对灵活。

链表与顺序表的对比
操作链表顺序表
访问元素O(n)O(1)
在头部插入/删除O(1)O(n)
在末部插入/删除O(n)O(1)
在中间插入/删除O(n)O(n)

单向链表

理解:单向的,指针头指向尾部

实现方式:(python)

'''
    单链表的实现

'''
#创建结点对象
class Node:
    def __init__(self,val):
        self.val=val
        self.next=None

class Singly_linked_list():
    #数组头节点创建,node=None声明没有元素
    def __init__(self,node=None):
        #__head私有化属性,不被外界访问
        self.__head=node

    #判断是否为空
    def is_empty(self):
        #判断头是否为空
        return self.__head==None

    #查看链表有多少个元素
    def length(self):
        #cur指向头
        cur=self.__head
        #记录有多少元素
        count=0
        #判断链表是否为空
        while cur != None:
            #不是加一
            count+=1
            #指针cur向后移动
            cur=cur.next
        return count
    #头部插入
    def headadd(self,val):
        #构建节点(将插入数值换成结点类型,)
        node=Node(val)
        #设置关联,头指向下一个,不能交换位置,交换位置会改变原本链表的连接关系
        #先改变元素next区域,在指向头
        node.next=self.__head
        self.__head=node

    #中间插入
    def middleadd(self,pos,val):
        if pos == 0:
            # 当pos=o是就是头部添加
            self.headadd(val)
        elif pos >=self.length()-1:
            # 当 pos大于链表长度就是尾部部添加
            self.tailadd(val)
        else:
            pre = self.__head
            #构建pre指针指向头节点的值
            count=0
            while count < (pos-1):
                count+=1
                pre=pre.next
            node=Node(val)
            node.next=pre.next
            pre.next=node

    #尾部插入
    def tailadd(self,val):
        node = Node(val)
        cur=self.__head
        #如果链表中没有元素
        if cur is None:
            self.headadd(val)
        else:
            while cur.next is not None:
                cur=cur.next
            cur.next=node


    #删除节点
    def remove(self,item):
        cur=self.__head
        pre=None
        while cur !=None:
        #遍历一遍
            if cur.val==item:
            #判断是否存在目标
                if cur== self.__head:
                    #如果是头节点,
                    self.__head=cur.next
                    break
                else:
                    #跳过这个节点
                    pre.next=cur.next
                break
            else:
                #二个游标必须相隔一个节点
                pre=cur
                cur=cur.next
    #遍历链表
    def walk(self):
        cur=self.__head
        while cur is not None:
            print(cur.val,end= ' ')
            cur=cur.next

    #查看节点是否存在
    def search(self,item):
        cur=self.__head
        while cur != None:
            if cur.val == item:
                return True
            else:
                #如果不存在就向后移动一位
                cur=cur.next
        return False

if __name__ == '__main__':
    a=Singly_linked_list()
    a.headadd(3)
    a.headadd(4)
    a.tailadd(6)
    a.headadd(7)
    a.middleadd(2,8)
    print(a.search(4))
    a.walk()
    a.remove(7)
    a.walk()

双向链表

理解:双向的,指针头指向尾部,尾部也指向头部

实现方式:(python,与单链表不同的是插入,删除,遍历)

 

 

 

'''
    双链表的实现

'''
#创建结点对象
class Node(object):
    def __init__(self,val):
    #定义节点
        self.val=val
        #前节点
        self.prev=None
        #后节点
        self.next=None


class Double_linked_list(object):
    #数组头节点创建,node=None声明没有元素
    def __init__(self,node=None):
        #__head私有化属性,不被外界访问
        self.__head=node
    #判断是否为空
    def is_empty(self):
        #判断头是否为空
        return self.__head is None

    #查看链表有多少个元素
    def length(self):
        #cur指向头
        cur=self.__head
        #记录有多少元素
        count=0
        #判断链表是否为空
        while cur != None:
            #不是加一
            count+=1
            #指针cur向后移动
            cur=cur.next
        return count

    #头部插入
    def headadd(self,val):
        #构建节点(将插入数值换成结点类型,)
        node=Node(val)
        node.next=self.__head
        self.__head=node
        node.next.prev=node

    #中间插入
    def middleadd(self,pos,val):
        if pos == 0:
            # 当pos=o是就是头部添加
            self.headadd(val)
        elif pos >=self.length()-1:
            # 当 pos大于链表长度就是尾部部添加
            self.tailadd(val)
        else:
            cur=self.__head
            count=0
            while count < pos:
                count+=1
                cur=cur.next
            #退出循环cur指向pos位置
            node=Node(val)
            node.next=cur
            node.prev=cur.prev
            cur.prev.next=node
            cur.prev=node

    #尾部插入
    def tailadd(self,val):
        node = Node(val)
        cur=self.__head
        #如果链表中没有元素
        if cur is None:
            self.__head=node
        else:
            while cur.next is not None:
                cur=cur.next
            cur.next=node
            node.prev=cur


    #删除节点
    def remove(self,item):
        cur=self.__head
        while cur !=None:
        #遍历一遍
            if cur.val==item:
            #判断是否存在目标
                if cur == self.__head:
                    #如果是头节点,
                    self.__head=cur.next
                    if cur.next:
                        #判断链表是否只有一个节点
                        cur.next.prev=None
                    break
                else:
                    #跳过这个节点
                    cur.prev.next=cur.next
                    if cur.next:
                        cur.next.prev=cur.prev
                break
            else:
                #二个游标必须相隔一个节点
                cur=cur.next
    #遍历链表
    def walk(self):
        cur=self.__head
        while cur is not None:
            print(cur.val,end= ' ')
            cur=cur.next

    #查看节点是否存在
    def search(self,item):
        cur=self.__head
        while cur != None:
            if cur.val == item:
                return True
            else:
                #如果不存在就向后移动一位
                cur=cur.next
        return False

if __name__ == '__main__':
    a=Double_linked_list()
    a.tailadd(6)
    a.headadd(7)
    a.headadd(3)
    a.headadd(4)
    a.middleadd(2,8)
    print(a.search(4))
    a.walk()
    a.remove(7)
    a.walk()

 

 

以上是关于数据结构与算法什么是链表?并用代码手动实现一个单向链表的主要内容,如果未能解决你的问题,请参考以下文章

链表1-数据结构与算法之Swift实现1

Java-链表(单向链表双向链表)

数据结构与算法详解什么是哈希表,并用代码手动实现一个哈希表

JavaScript单向链表的创建遍历插入删除操作

php实现数据结构单向链表

数据结构--队列的实现(单向链表方式)