一、定义
链表是一种基本的数据结构,由一系列节点组成,包括数据域和指针域,数据域用来存放值,指针域用来指向下一个节点。区别于数组的特点,数组需要已知大小且连续的存储空间,而链表不一定是连续的存储空间,所以使用链表可以有效的利用内存空间。
二、链表分类
- 单向链表:每个节点只有一个指针指向下一个节点,最后一个节点指向NULL。
- 双向链表:每个节点有两个指针,分别指向上一个节点和下一个节点,可以再O(1)时间内实现向前和向后遍历。
- 循环链表:再单向或双向链表的基础上,将最后一个节点的指针指向头节点。
三、链表的操作
链表的基本操作有:插入、删除、查找、遍历。
- 插入操作:可以在链表头或尾插入节点,也可以在指定位置插入节点。
- 删除操作:可以删除指定节点或按照值删除节点。
- 查找操作:可以查找指定节点或按照值查找节点。
- 遍历操作:可以遍历整个链表,输出每个节点的值或其它操作。
一、定义
链表是一种基本的数据结构,由一系列节点组成,包括数据域和指针域,数据域用来存放值,指针域用来指向下一个节点。区别于数组的特点,数组需要已知大小且连续的存储空间,而链表不一定是连续的存储空间,所以使用链表可以有效的利用内存空间。
二、链表分类
- 单向链表:每个节点只有一个指针指向下一个节点,最后一个节点指向NULL。
- 双向链表:每个节点有两个指针,分别指向上一个节点和下一个节点,可以再O(1)时间内实现向前和向后遍历。
- 循环链表:再单向或双向链表的基础上,将最后一个节点的指针指向头节点。
三、链表的操作
链表的基本操作有:插入、删除、查找、遍历。
- 插入操作:可以在链表头或尾插入节点,也可以在指定位置插入节点。
- 删除操作:可以删除指定节点或按照值删除节点。
- 查找操作:可以查找指定节点或按照值查找节点。
- 遍历操作:可以遍历整个链表,输出每个节点的值或其它操作。
四、单向链表
单向链表是由若干个节点组成的数据结构,每个结构包含两个部分:数据域和指针域。数据域存储节点的数据,指针域指向下一个节点的地址。
4.1定义一个单向链表
struct ListNode{
int val; //节点的值
struct ListNode* next; //指向下一个节点
};
4.2插入操作
//头插法
struct ListNode* insertAtHead(struct ListNode* head, int val){
struct ListNode* new_node = (struct ListNode*)malloc(sizeof(struct ListNode));
new_node->val = val;
new_node->next = head;
return new_node;
}
//尾插法
struct ListNode* insertAtTail(struct ListNode* head,int val){
struct ListNode* new_node = (struct ListNode*)malloc(sizeof(struct ListNode));
new_node->val = val;
new_node->next = NULL;
if(head == NULL){
return new_node;
}
struct ListNode* p = head;
while (p->next != NULL){
p = p->next;
}
p->next = new_node;
return head;
}
//在指定位置插入节点
struct ListNode* insertAtIndex(struct ListNode* head, int index, int val){
int i=0;
struct ListNode* new_node = (struct ListNode*)malloc(sizeof(struct LIstnode));
new_node->val = val;
if(index == 0){
new_node->next = dead;
return new_node;
}
struct ListNode* p = head;
while (i < index-1 && p != NULL){
p = p->next;
i++;
}
if (p == NULL){
free(new_node);
return head;
}
new_node->next = p->next;
p->next = new_node;
return head;
}
4.3删除操作
可以删除链表的指定位置或者指定值的节点。
//删除指定位置的节点
struct ListNode* deleteAtIndex(struct ListNode* head, int index){
int i = 0;
if (head == NULL){
return NULL;
}
if (index == 0){
struct ListNode* temp = head;
head = head->next;
free(temp);
return head;
}
struct ListNode* p = head;
while(i < index-1 && p != NULL){
p = p->next;
i++;
}
if (p == NULL || p->next ==NULL){
return head;
}
struct ListNode* temp = p->next;
p->next = p->next->next;
free(temp);
return head;
}
//删除指定值的节点
struct ListNode* deleteNode(struct ListNode* head, int val){
struct ListNode* p = head;
struct ListNode* prev = NULL;
while (p != NULL && p->val != val){
prev = p;
p = p->next;
}
if (p == NULL){
return head;
}
if (prev == NULL){
head = head->next;
}else{
prev->next = p->next;
}
free(p);
return head;
}
4.4修改操作
修改操作可以修改该指定位置或指定值的节点的值。
//修改指定位置的节点的值
struct ListNode* modifyAtIndex(struct ListNode* head, int index, int val){
struct ListNode* p = head;
int i=0;
while (i < index && p!= NULL){
p = p->next;
i++;
}
if (p == NULL){
return head;
}
p->val = val
return head;
}
//修改指定值的节点的值
struct ListNode* modifyNode(struct ListNode* head, int old_val, int new_val){
struct ListNode* p = head;
while(p != NULL && p->val != old_val){
p= p->next;
}
if(p == NULL){
return head;
}
p->val = new_val;
return head;
}
4.5查找操作
链表的查找操作可以查找指定位置或指定值的节点。
//查找指定位置的定节点的值
int getValAtIndex(struct ListNode* head, int index){
struct ListNode* = head;
int i = 0;
while(i < index && p !=NULL){
p= p->next;
i++;
}
if (p == NULL){
return -1;
}
return p->val;
}
//查找指定值的节点的位置
int getIndexByVal(struct LsitNode* head, int val){
struct ListNode* p = head;
int i= 0;
while (p != NULL && p->val != val){
p = p->next;
i++;
}
if (p == NULL){
return -1;
}
return i;
}