目录
链表
链表是一种基础的数据结构,数据元素之间的逻辑关系是由结点中的指针指示的。一个链表由一系列结点组成,每个结点包括两个部分:一个是存储数据元素的数据域(图中的data),另一个是存储下一个结点地址的指针域(图中的next)。
与数组相比,链表不要求逻辑上相邻的元素在物理上也相邻,链表允许插入和移除表上任意位置上的节点。
C语言中单链表的表示
定义
#include <stdlib> //有malloc calloc free exit的函数声明
#include <malloc> //有malloc calloc free函数的声明
typedef struct Node //这里我将struct Node替换为Node
{ int data;
struct Node *next; //next指针指向下一个结点的地址
}Node;
初始化单链表
C语言允许建立内存动态分配区域,以存放一些临时的数据,这些数据在需要时随时开辟,不需要时随时释放。这个存储区称为堆(heap),此类数据只能通过指针来引用。
C语言中使用malloc函数进行动态内存分配,其功能是在堆区分配连续的size个字节的存储空间并且返回这段存储空间开头位置的地址,如果内存分配失败会返回空指针。
Node* InitList() {
Node* head = (Node*)malloc(sizeof(Node)); //定义一个头结点,头节不含有数据
head->next = NULL;
return head;
}
新结点的创建
示例:创建一个data值为10的结点。
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = 10;
newNode->next = NULL;
结点值的表示
- 可以通过 变量名.成员名 的方式访问一个结构体变量成员的值
- 可以通过 指针->成员名 的方式访问一个结构体变量成员的值
struct Node p;
struct Node *q = &p;
printf("%d\n", p.data);
printf("%d\n", q->data);
上面的语句都将输出同一个结点的data值。
表达式q->data和(*q).data是等价的,前者是指向该结构体的存储单元,而后者是对指针的间接引用,并对结构成员运算符的成员data进行访问。
结点的释放
free(p); //释放节点p,free函数的实参必须是一个指向动态内存空间的指针
Go语言中单链表的表示
定义
Go语言与C语言类似,也有指针,使用指针+结构体的方式来实现链表
// 结点
type Node struct {
Val int //与C语言不同的是,Go语言定义变量时,类型名写在变量名之后
Next *Node
}
//链表
type List struct {
head *Node
}
使用new函数创建新结点
Go语言中有一个内置函数new,可以用于动态分配内存并返回指向该内存的指针。然后再对结点进行赋值,未手动赋值的变量自动赋空值。对于int类型的字段,默认为0,对于指针类型的字段,默认为nil。
如:创建一个Val值为1的结点。
newNode := new(Node)
newNode.Val = 1
使用结构体实例化一个结点
在Go语言中,可以使用结构体实例化来创建一个节点。
如:创建一个Val值为10的结点。
newNode := &Node{
Val: 10,
next: nil,
}
结构体实例化结点与new函数创建新结点的区别
-
使用结构体字面量的方式,我们可以直接在大括号内设置节点的字段值。这种方式更加直观和灵活,可以在创建节点的同时初始化字段的值。
-
使用new函数创建节点时,会分配一块零值内存,并返回指向该内存的指针。然后,我们可以通过指针访问节点的字段,并设置它们的值。需要注意的是,使用new函数创建的节点,默认会被初始化为对应类型的零值。
总结来说,使用结构体字面量实例化节点的方式更加简洁和灵活,而new函数创建节点的方式则更加明确,可以在后续代码中逐个设置字段的值。具体使用哪种方式,取决于个人的编程习惯和需求。
结点值的表示
Go语言中结点值的表示也是使用 结点名.变量名 的方式。
head.Val
结点的释放
在Go语言中,不需要手动释放内存。Go语言的垃圾回收器会自动管理内存的分配和释放,当一个对象不再被引用时,垃圾回收器会自动识别并回收这块内存空间。
Python中单链表的表示
C语言使用指针控制内存来实现链表,在Python中,虽然没有显式的指针概念,但是可以使用引用来实现链表。引用在Python中类似于指针,可以指向内存中的对象。
定义
# 链节点类
class Node:
def __init__(self, val=0, next=None): # 设置默认值
self.val= val
self.next = next
# 链表类
class List:
def __init__(self):
self.head = None
新结点的创建
在Python中,可以使用节点类来创建新的结点对象。
如:创建一个val值为1的结点。
newNode = Node(1)
结点值的表示
Python中结点值的可以使用 结点实例.实例变量 来表示
cur.val# 表示cur这个节点的val值
结点的释放
在Python中,不需要显式地释放节点的内存,因为Python有自动的垃圾回收机制。