- C语言数据结构与算法教程
- C语言实现的数据结构与算法 - 首页
- C语言实现的数据结构与算法 - 概述
- C语言实现的数据结构与算法 - 环境配置
- C语言实现的数据结构与算法 - 算法
- C语言实现的数据结构与算法 - 概念
- C语言实现的数据结构与算法 - 数组
- C语言实现的数据结构与算法 - 链表
- C语言实现的数据结构与算法 - 双向链表
- C语言实现的数据结构与算法 - 循环链表
- C语言实现的数据结构与算法 - 栈
- C语言实现的数据结构与算法 - 表达式解析
- C语言实现的数据结构与算法 - 队列
- C语言实现的数据结构与算法 - 优先队列
- C语言实现的数据结构与算法 - 树
- C语言实现的数据结构与算法 - 哈希表
- C语言实现的数据结构与算法 - 堆
- C语言实现的数据结构与算法 - 图
- C语言实现的数据结构与算法 - 搜索技术
- C语言实现的数据结构与算法 - 排序技术
- C语言实现的数据结构与算法 - 递归
- C语言实现的数据结构与算法 - 有用资源
- C语言实现的数据结构与算法 - 快速指南
- C语言实现的数据结构与算法 - 有用资源
- C语言实现的数据结构与算法 - 讨论
C语言实现的数据结构与算法 - 链表
概述
链表是由一系列链接组成的序列,每个链接都包含一个指向另一个链接的指针。链表是仅次于数组的第二常用数据结构。以下是一些理解链表概念的重要术语。
链接 (Link) − 链表的每个链接都可以存储称为元素的数据。
下一个 (Next) − 链表的每个链接都包含一个指向下一个链接的指针,称为 Next。
链表 (LinkedList) − 链表包含一个指向第一个链接的指针,称为 First。
链表表示
根据上图所示,以下是要考虑的重要事项。
链表包含一个称为 first 的链接元素。
每个链接都包含一个或多个数据字段和一个称为 next 的链接字段。
每个链接都使用其 next 链接与其下一个链接链接。
最后一个链接的链接为 null,用于标记列表的结尾。
链表的类型
以下是链表的各种类型。
单向链表 (Simple Linked List) − 只能向前导航项目。
双向链表 (Doubly Linked List) − 可以向前和向后导航项目。
循环链表 (Circular Linked List) − 最后一个项目包含指向第一个元素的 next 指针,而第一个元素包含指向最后一个元素的 prev 指针。
基本操作
以下是链表支持的基本操作。
插入 (Insertion) − 在列表开头添加一个元素。
删除 (Deletion) − 删除列表开头的元素。
显示 (Display) − 显示整个列表。
搜索 (Search) − 使用给定的键搜索元素。
删除 (Delete) − 使用给定的键删除元素。
插入操作
插入是一个三步过程:
创建一个包含提供的数据的新链接。
将新链接指向旧的第一个链接。
将第一个链接指向这个新链接。
//insert link at the first location
void insertFirst(int key, int data){
//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
//point it to old first node
link->next = head;
//point first to new first node
head = link;
}
删除操作
删除是一个两步过程:
获取第一个链接指向的链接作为临时链接。
将第一个链接指向临时链接的下一个链接。
//delete first item
struct node* deleteFirst(){
//save reference to first link
struct node *tempLink = head;
//mark next to first link as first
head = head->next;
//return the deleted link
return tempLink;
}
导航操作
导航是一个递归步骤过程,是许多操作(如搜索、删除等)的基础:
获取第一个链接指向的链接作为当前链接。
检查当前链接是否不为空,并显示它。
将当前链接指向当前链接的下一个链接,并转到上述步骤。
注意:
//display the list
void printList(){
struct node *ptr = head;
printf("\n[ ");
//start from the beginning
while(ptr != NULL){
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
printf(" ]");
}
高级操作
以下是为列表指定的高级操作。
排序 (Sort) − 基于特定顺序对列表进行排序。
反转 (Reverse) − 反转链表。
排序操作
我们使用冒泡排序来排序列表。
void sort(){
int i, j, k, tempKey, tempData ;
struct node *current;
struct node *next;
int size = length();
k = size ;
for ( i = 0 ; i < size - 1 ; i++, k-- ) {
current = head ;
next = head->next ;
for ( j = 1 ; j < k ; j++ ) {
if ( current->data > next->data ) {
tempData = current->data ;
current->data = next->data;
next->data = tempData ;
tempKey = current->key;
current->key = next->key;
next->key = tempKey;
}
current = current->next;
next = next->next;
}
}
}
反转操作
以下代码演示了如何反转单链表。
void reverse(struct node** head_ref) {
struct node* prev = NULL;
struct node* current = *head_ref;
struct node* next;
while (current != NULL) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head_ref = prev;
}
示例
LinkedListDemo.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
int key;
struct node *next;
};
struct node *head = NULL;
struct node *current = NULL;
//display the list
void printList(){
struct node *ptr = head;
printf("\n[ ");
//start from the beginning
while(ptr != NULL){
printf("(%d,%d) ",ptr->key,ptr->data);
ptr = ptr->next;
}
printf(" ]");
}
//insert link at the first location
void insertFirst(int key, int data){
//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
//point it to old first node
link->next = head;
//point first to new first node
head = link;
}
//delete first item
struct node* deleteFirst(){
//save reference to first link
struct node *tempLink = head;
//mark next to first link as first
head = head->next;
//return the deleted link
return tempLink;
}
//is list empty
bool isEmpty(){
return head == NULL;
}
int length(){
int length = 0;
struct node *current;
for(current = head; current!=NULL;
current = current->next){
length++;
}
return length;
}
//find a link with given key
struct node* find(int key){
//start from the first link
struct node* current = head;
//if list is empty
if(head == NULL){
return NULL;
}
//navigate through list
while(current->key != key){
//if it is last node
if(current->next == NULL){
return NULL;
} else {
//go to next link
current = current->next;
}
}
//if data found, return the current Link
return current;
}
//delete a link with given key
struct node* delete(int key){
//start from the first link
struct node* current = head;
struct node* previous = NULL;
//if list is empty
if(head == NULL){
return NULL;
}
//navigate through list
while(current->key != key){
//if it is last node
if(current->next == NULL){
return NULL;
} else {
//store reference to current link
previous = current;
//move to next link
current = current->next;
}
}
//found a match, update the link
if(current == head) {
//change first to point to next link
head = head->next;
} else {
//bypass the current link
previous->next = current->next;
}
return current;
}
void sort(){
int i, j, k, tempKey, tempData ;
struct node *current;
struct node *next;
int size = length();
k = size ;
for ( i = 0 ; i < size - 1 ; i++, k-- ) {
current = head ;
next = head->next ;
for ( j = 1 ; j < k ; j++ ) {
if ( current->data > next->data ) {
tempData = current->data ;
current->data = next->data;
next->data = tempData ;
tempKey = current->key;
current->key = next->key;
next->key = tempKey;
}
current = current->next;
next = next->next;
}
}
}
void reverse(struct node** head_ref) {
struct node* prev = NULL;
struct node* current = *head_ref;
struct node* next;
while (current != NULL) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head_ref = prev;
}
main() {
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertFirst(5,40);
insertFirst(6,56);
printf("Original List: ");
//print list
printList();
while(!isEmpty()){
struct node *temp = deleteFirst();
printf("\nDeleted value:");
printf("(%d,%d) ",temp->key,temp->data);
}
printf("\nList after deleting all items: ");
printList();
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,1);
insertFirst(5,40);
insertFirst(6,56);
printf("\nRestored List: ");
printList();
printf("\n");
struct node *foundLink = find(4);
if(foundLink != NULL){
printf("Element found: ");
printf("(%d,%d) ",foundLink->key,foundLink->data);
printf("\n");
} else {
printf("Element not found.");
}
delete(4);
printf("List after deleting an item: ");
printList();
printf("\n");
foundLink = find(4);
if(foundLink != NULL){
printf("Element found: ");
printf("(%d,%d) ",foundLink->key,foundLink->data);
printf("\n");
} else {
printf("Element not found.");
}
printf("\n");
sort();
printf("List after sorting the data: ");
printList();
reverse(&head);
printf("\nList after reversing the data: ");
printList();
}
输出
如果我们编译并运行上述程序,它将产生以下输出:
Original List: [ (6,56) (5,40) (4,1) (3,30) (2,20) (1,10) ] Deleted value:(6,56) Deleted value:(5,40) Deleted value:(4,1) Deleted value:(3,30) Deleted value:(2,20) Deleted value:(1,10) List after deleting all items: [ ] Restored List: [ (6,56) (5,40) (4,1) (3,30) (2,20) (1,10) ] Element found: (4,1) List after deleting an item: [ (6,56) (5,40) (3,30) (2,20) (1,10) ] Element not found. List after sorting the data: [ (1,10) (2,20) (3,30) (5,40) (6,56) ] List after reversing the data: [ (6,56) (5,40) (3,30) (2,20) (1,10) ]