链表:
一:什么是链表
链表是指结构体变量与结构体变量通过结构体指针连接起来。
从下图可以看出链表就是结构体通过结构体指针串起来的一个东西,他们之间相互联系,就像一个链子连在一起一样。
二: 静态链表
struct Node {
int date; //数据域
struct Node* next; //指针域
};
int main()
{
struct Node node1 = {1,NULL};
struct Node node2 = {1,NULL};
struct Node node3 = {1,NULL};
node1.next = &node2;
node2.next = &node3;
return 0;
} // 静态链表
三:动态链表:动态内存申请 + 模块化设计
1. 创建链表(创建链表头并初始化)
struct Node* createList()
{
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node)); //动态内存申请
headNode->date = 1;
headNode->next = NULL;
return headNode;
}
2. 创建结点
struct Node* createNode(int date){
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->date = date;
newNode->next = NULL;
return newNode;
}
3. 结点插入(头插法)
// 插入结点 ,表头法插入.
void insertNodeByhead(struct Node* headNode , int date){
struct Node* newNode = createNode(date);
newNode->next = headNode->next;
headNode->next = newNode;
}
4. 遍历结点
void printList (struct Node* headNode){
struct Node* pMove = headNode->next;
while(pMove){
printf("%d",pMove->date);
pMove = pMove->next;
}
printf("\n");
}
5. 删除结点,根据数据删除
void delectNodebyapposion(struct Node* headNode , int posDate){
struct Node* posNode = headNode->next;
struct Node* posNodeFront = headNode;
if(posNode == NULL){
printf("链表为空,无法删除");
}
else
while(posNode->date != posDate){
posNodeFront = posNode;
posNode = posNodeFront->next;
if(posNode == NULL){
printf("没有找到相关结点");
return;
}
}
posNodeFront->next = posNode->next;
free(posNode);
}
四:实际项目应用
根据实际应用改变结点内的数据结构类型进行。
# include <stdio.h>
# include <stdlib.h>
struct student{
char *name;
int id;
int score;
};
struct Node {
struct student date; //数据域
struct Node* next; //指针域
};
//创建表头
struct Node* createList()
{
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
headNode->date.id = 0;
headNode->date.name = NULL;
headNode->date.score = 0;
headNode->next = NULL;
return headNode;
}
// 创建结点
struct Node* createNode(int id,char* name, int score){
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->date.id = id;
newNode->date.name = name;
newNode->date.score = score;
newNode->next = NULL;
return newNode;
}
void printList (struct Node* headNode){
struct Node* pMove = headNode->next;
while(pMove){
printf(" ID:%d name:%s score:%d \n",pMove->date.id,pMove->date.name,pMove->date.score);
pMove = pMove->next;
}
printf("\n");
}
// 插入结点 ,表头法插入.
void insertNodeByhead(struct Node* headNode , int id,char* name, int score){
struct Node* newNode = createNode(id,name,score);
newNode->next = headNode->next;
headNode->next = newNode;
}
// 链表删除,指定位置删除.
//
//void delectNodebyapposion(struct Node* headNode , int posDate){
// struct Node* posNode = headNode->next;
// struct Node* posNodeFront = headNode;
// if(posNode == NULL){
// printf("链表为空,无法删除");
// }
// else
// while(posNode->date != posDate){
// posNodeFront = posNode;
// posNode = posNodeFront->next;
// if(posNode == NULL){
// printf("没有找到相关结点");
// return;
// }
// }
//
// posNodeFront->next = posNode->next;
// free(posNode);
//}
int main()
{
struct Node* list = createList();
insertNodeByhead(list,1,"xiaoming",100);
insertNodeByhead(list,2,"xiaogang",60);
insertNodeByhead(list,3,"xiaohong",70);
printList(list);
return 0;
}
输出结果:
注意: 大部分代码和前面介绍动态链表的创建一模一样,只是在这个地方:
我们将结点的数据域 date变成了一个 student的结构体,而后面的代码我们只需要根据这个stduent结构体的成员变量进行修改即可。