有序单链表插入——C语言

以下内容要求有一定指针和链表基础,请配合画图理解

1.首先我们定义一个头文件(slink.h),用来声明链表的结点数据类型,以及相关函数

/*
** 定义一个有序单链表的操作接口
*/
#include  //动态分配内存声明文件
#include  //断言函数声明文件
#include  //标准输入输出声明文件

#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!!

你可能感兴趣的:(C语言,数据结构,c语言,链表,数据结构)