以下内容要求有一定指针和链表基础,请配合画图理解
1.首先我们定义一个头文件(slink.h),用来声明链表的结点数据类型,以及相关函数
/*
** 定义一个有序单链表的操作接口
*/
#include <malloc.h> //动态分配内存声明文件
#include <assert.h> //断言函数声明文件
#include <stdio.h> //标准输入输出声明文件
#define LINK_TYPE int //链表存储数据类型
/*
** 定义结点数据类型
*/
typedef struct NODE{
LINK_TYPE value;
struct NODE *next;
}Node;
/*
** 把数据插入到有序链表中(常规版)
** 参数为指向根指针的指针和要插入的值
*/
void LinkInsert(Node **Root, LINK_TYPE value);
/*
** 把数据插入到有序链表中(终极版)
** 参数为指向根指针的指针和要插入的值
*/
void LinkInsert_EX(Node **Root, LINK_TYPE value);
/*
** 遍历输出链表,并返回链表长度
** 参数为根指针(根指针指向链表第一个结点)
*/
int printLink(Node *root);
2.再创建一个文件(slink.c)具体实现单链表插入函数
#include "slink.h"
//常规版插入数据
void LinkInsert(Node **Root, LINK_TYPE value){
Node *current = *Root;
Node *previous = NULL;
while((value > current->value) && (current->next != NULL)){
previous = current;
current = current->next;
}
//新创建一个指向Node的指针
//malloc会返回一个void型指针,该指针指向一片内存空间
//参数(字节数)决定内存空间大小,指针类型会根据赋值对象进行转换
Node *new = malloc(sizeof( Node ));
//使用完malloc后要使用断言函数判断是否分配成功
assert(new != NULL);
new->value = value;
//插头
if(previous == NULL){
new->next = current;
*Root = new;
}
//插中
else if(value <= current->value){
new->next = current;
previous->next = new;
}
//插尾
else{
current->next = new;
new->next = NULL;
}
}
//终极版插入数据
void LinkInsert_EX(Node **Root, LINK_TYPE value){
Node *current;
//转换思路,链表要插入的结点关心的是哪个指针指向它
//不管这个指向它的指针在哪个位置。所以我们只关注
//指向当前结点的next指针的指针(画图更易理解)
while((current = *Root) && (value > current->value)){
Root = &(current->next); //关键之处
}
Node *new = malloc(sizeof( Node ));
assert( new != NULL );
new->value = value;
new->next = current;
*Root = new;
}
//遍历输出链表,并返回长度
int printLink(Node *root){
Node *findnode = root;
int count = 0;
while(findnode != NULL){
++count;
printf("%d", findnode->value);
findnode = findnode->next;
if(findnode != NULL){
printf("->");
}else{
break;
}
}
return count;
}
3.再编写一个主函数(main.c)来测试有序单链表插入操作
#include "slink.c"
int main(){
Node *root; //根指针,指向链表第一个结点
Node **Root; //根指针的指针
Node a, b, c;
a.value = 3;
b.value = 5;
c.value = 10;
Root = &root;
root = &a;
a.next = &b;
b.next = &c;
c.next = NULL;
printf("\n链表长度为:%d",printLink(*Root));
//调用常规版插入链表函数
LinkInsert(Root, 2);
LinkInsert(Root, 6);
LinkInsert(Root, 9);
LinkInsert(Root, 13);
printf("\n\n");
printf("\n链表长度为:%d",printLink(*Root));
printf("\n\n");
//调用终极版插入链表函数
LinkInsert_EX(Root, 1);
LinkInsert_EX(Root, 8);
LinkInsert_EX(Root, 16);
printf("\n链表长度为:%d",printLink(*Root));
}
控制台输出为:
3->5->10
链表长度为:3
2->3->5->6->9->10->13
链表长度为:7
1->2->3->5->6->8->9->10->13->16
链表长度为:10
总结:如果有好好画图和敲代码理解,相信对C语言的指针一定会有更进一步的了解,接下来我还会发双链表,C语言yyds!!