一、 链表的组成:
头指针(Header)和若干个节点(节点包括了数据域和指针域),最后一个节点要指向空。
链表的实现原理:头指针指向链表的第一个节点,然后第一个节点中的指针指向下一个节点,然后依次指到最后一个节点,这样就构成了一条链表。
1.定义一个结点
struct Node{
int data; //存放数据
struct Node* next; //指针,用来访问结点数据,也可以遍历指向下一个结点
};
2.创造链表的头结点:
struct Node* creatNode(){
struct Node *ptmp;
ptmp = (struct Node*)malloc(sizeof(struct Node)); //为结点申请分配内存
//malloc在栈上分配内存
if(ptmp == NULL){
printf("malloc failed\n"); //内存分配失败
}
memset(ptmp, '\0', sizeof(struct Node)); //清零
//将结点初始化
ptmp->data = 0;
ptmp->next = NULL;
return ptmp;
}
3.链表增加结点:
void addNode(struct Node* head, int data){ //data为新加结点的值
struct Node *pnode;
pnode = head;
if(pnode == NULL){ //头结点是否为空
printf("This linklist is NULL");
return;
}
struct Node *newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
if(newNode == NULL){
printf("malloc failed\n"); //为新结点分配内存
}
newNode->data = data;
newNode->next = NULL;
while(pnode->next != NULL){ //找到链表的尾
pnode = pnode->next;
}
pnode->next = newNode; //将新创的结点加入链表
return;
}
4.遍历链表
void printLinklist(struct Node* phead){
struct Node *ptmp;
ptmp = phead;
if(ptmp == NULL){
printf("This linklist is NULL");
return;
}
while(ptmp != NULL){
printf("%d\t", ptmp->data);
ptmp = ptmp->next;
}
puts(""); //遍历结束后换行
return;
}
5.删除某个位置的结点L1
5.1 先得到想要删除节点的前一个结点记为L2,即查找某个位置的值
struct Node* getPosTolinklist(struct Node* phead, int pos){
struct Node *ptmp;
ptmp = phead;
if(ptmp == NULL){
printf("This linklist is NULL");
return NULL;
}
while(pos--){ //注:从0开始计数的位置
ptmp = ptmp->next;
}
return ptmp;
}
5.2将L2结点的next等于L1的next即完成结点的删除
void deleteNodeTolinklist(struct Node* phead, int pos){
struct Node *ptmp;
struct Node *deleteNode;
ptmp = phead;
if(ptmp == NULL){
printf("This linklist is NULL");
return;
}
ptmp = getNodePosTolinklist(phead, pos-1); //得到想要删除结点的前一个结点
deleteNode = ptmp->next;
ptmp->next = deleteNode->next;
free(deleteNode); //释放结点
return;
}
6.更改某个位置结点的值
利用5.1得到更改位置的结点,对该结点的data重新赋值即可。
void changNodedataToLinklist(struct Node* phead, int pos, int data){
struct Node *ptmp;
struct Node *changeNode;
ptmp = phead;
if(ptmp == NULL){
printf("This linklist is NULL");
return;
}
changeNode = getNodePosTolinklist(phead, pos); //得到想要更改位置的结点
changeNode->data = data; // 更改data值
return;
}
下面是我写的一个完整demo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int data;
int pos; // 可以让用户自定义pos的值
struct Node *phead;
phead = creatNode();
int i;
i = 5;
while(i--){ //为链表添加5个结点
printf("请输入要插入链表的值");
scanf("%d", &data);
addNode(phead, data);
}
printLinklist(phead);
deleteNodeTolinklist(phead, 4); // 可以用scanf输入pos的值,这里直接设置为4
printLinklist(phead);
changNodedataToLinklist(phead, 0, 100); //可以用scanf输入pos的值,这里直接设置为0
// data直接设置为100
printLinklist(phead);
return 0;
}