C 语言实现单链表

单链表的实现有两种:有无头结点
        一般有头节点的会容易实现。写在这里方便以后查看。下面的这一些功能, 只是自己一些臆想出来的。之所以把功能做出来,是为了增加自己的一些积累。在实际的工程当中,应当根据具体应用场景进行相应的改动,大致的框架是不会怎么改动的。
下面的函数都通过了我的验证,在Ubuntu上使用gdb调试器验证的。
关于命名要好好想一下

目前我能想到的拓展:

  • ascending order (升序)、descending order (降序)、unordered(无序)
  • 有无头结点
  • 遇到相同关键值改如何处理
  • 传参是头指针还是头指针地址
  • 元素的类型 emmmmmm…

这些拓展有时间就实现一下吧,其实都差不多

/********************************************************************************
* Copyright(c) 2019-20xx
* All right resered.
*
* @file  	single_linked_list.h
* @author 	hongsmallgod
* @version	V1.0.1
* @data		2019-9-12 10:56:21
* @brief	单链表头文件
********************************************************************************/
#ifndef _SINGLE_LINKED_LIST_H
#define _SINGLE_LINKED_LIST_H

#undef element
#define element int

typedef struct node node;
struct node {
    element data;
    node *next;
};

extern int sll_insert1(node *head, element data);
extern int sll_insert2(node *head, element data);
extern int sll_insert3(node *head, element data);
extern int sll_delete1(node *head, element data);
extern int sll_delete2(node *head, element data);
#if 0
extern void sll_traversal(node *head);
extern node *create_sll(void);
extern void sll_sort(node *head);
#endif
extern int sll_insert4(node *head, element data);
extern int sll_insert5(node *head, element data);
extern int sll_delete3(node *head, element data);

extern void sll_destroy(node *head);
extern size_t get_sll_node_num(node *head);
extern int sll_insert6(node **rootp, element data);
extern int sll_delete_tail(node *head);
extern int sll_delete_head(node *head);
extern int sll_get_head(node *head, element *data);
extern int sll_get_tail(node *head, element *data);
extern int sll_get_and_delete_head(node *head, element *data);
extern int sll_get_and_delete_tail(node *head, element *data);
#endif
/********************************************************************************
* Copyright(c) 2019-20xx
* All right resered.
*
* @file  	single_linked_list.c
* @author 	hongsmallgod
* @version	V1.0.1
* @data		2019-9-12 10:56:21
* @brief	单链表源文件
********************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "single_linked_list.h"

/*
** function  : sll_insert1
** author	 : hongsmallgod
** brief     : 升序单链表插入函数, 如果链表中有相同的值, 不进行插入
** argument  : @head: 头结点指针; @data: 关键值
** return 	 : 1: 插入成功; -1: 内存不足; 0:链表当中有相同的内容
*/
int sll_insert1(node *head, element  data)
{
    node *current = head;
    node *new = (node *)malloc(sizeof(node));
    if (NULL == new)
        return -1;
    new->data = data;

    for (; current->next && current->next->data <= data; current = current->next) {
        if (current->next->data == data)
            return 0;
    }
    new->next = current->next;
    current->next = new;

    return 1;
}

/*
** function  : sll_insert2 (单链表的插入函数, 区别不大)
** author	 : hongsmallgod
** brief     : 升序单链表插入函数, 如果链表中有相同的值, 插入到最后
** argument  : @head: 头结点指针; @data: 关键值
** return 	 : 1: 删除成功; -1: 内存不足;
*/
int sll_insert2(node *head, element  data)
{
    node *current = head;
    node *new = (node *)malloc(sizeof(node));
    if (NULL == new)
        return -1;
    new->data = data;

    for (; current->next && current->next->data <= data; current = current->next);

	new->next = current->next;
	current->next = new;
    return 1;
}

/*
** function  : sll_insert3 (单链表的插入函数, 区别不大)
** author	 : hongsmallgod
** brief     : 升序单链表插入函数, 如果链表中有相同的值, 插入到起始
** argument  : @head: 头结点指针; @data: 关键值
** return 	 : 1: 删除成功; -1: 内存不足;
*/
int sll_insert3(node *head, element  data)
{
    node *current = head;
    node *new = (node *)malloc(sizeof(node));
    if (NULL == new)
        return -1;
    new->data = data;

    for (; current->next && current->next->data < data; current = current->next);

	new->next = current->next;
	current->next = new;
    return 1;
}

/*
** function  : sll_delete1
** author	 : hongsmallgod
** brief     : 升序单链表节点删除函数, 如果相邻节点有相同的值, 删除第一个
** argument  : @head: 链表头结点指针; @data: 关键值
** return 	 : 1: 删除成功; 0: 链表当中没有所要删除的元素
*/
int sll_delete1(node *head, element  data)
{
    node *current = head;
    node *tmp = NULL;
    for (; current->next; current = current->next) {
        if (current->next->data == data) {
        	tmp = current->next->next;
        	free(current->next);
            current->next = current->next->next;
            return 1;
        }
        if (current->next->data > data)
            return 0;
    }
    return 0;
}

/*
** function  : sll_delete2
** author	 : hongsmallgod
** brief     : 升序单链表节点删除函数, 如果相邻节点有相同的值, 一并删除
			   例: 2 2 1 2 3 4 5 6(这个不是升序链表), 调用这个函数删除 2 , 结果  1 3 4 5 6
** argument  : @head: 链表头结点指针; @data: 关键值
** return 	 : 1: 删除成功; 0: 链表当中没有所要删除的元素
*/
int sll_delete2(node *head, element  data)
{
    node *current = head;
    node *tmp = NULL;
    int status = 0;
    while (current->next) {
        if (current->next->data == data) {
        	tmp = current->next->next;
        	free(current->next);
            current->next = tmp ;
            status = 1;
            continue;
        }
        if (current->next->data > data)
            break;
        current = current->next;
    }

    if (1 == status)
        return 1;
    return 0;
}
#if 0
/*
** function  : sll_traversal
** author	 : hongsmallgod
** brief     : 遍历单链表, 只适用于 数据域为 int 型数据
** argument  : @head: 链表头结点指针
** return 	 : none
*/
void sll_traversal(node *head)
{
    node *current = head->next;
    while (current) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}
#endif
/*
** function  : sll_insert4
** author	 : hongsmallgod
** brief     : 无序单链表插入函数, 插入到链表尾部
** argument  : @head: 头结点指针; @data: 关键值
** return 	 : 1: 插入成功; -1: 内存不足
*/
int sll_insert4(node *head, element  data)
{
    node *current = head;
    node *new = NULL;
    new = (node *)malloc(sizeof(node));
    if (NULL == new)
        return -1;
    new->data = data;
    new->next = NULL;
    for (; current->next; current = current->next);
    current->next = new;
    return 1;
}

/*
** function  : sll_insert5
** author	 : hongsmallgod
** brief     : 无序单链表插入函数, 插入到链表头
** argument  : @head: 头结点指针; @data: 关键值
** return 	 : 1: 删除成功; -1: 内存不足;
*/
int sll_insert5(node *head, element  data)
{
    node *new = (node *)malloc(sizeof(node));
    if (NULL == new)
        return -1;
    new->data = data;

    new->next = head->next;
    head->next = new;
    return 1;
}

/*
** function  : sll_delete3
** author	 : hongsmallgod
** brief     : 单链表节点删除函数, 如果链表有相同的值, 一并删除
** argument  : @head: 链表头结点指针; @data: 关键值
** return 	 : 1: 删除成功; 0: 链表当中没有所要删除的元素
*/
int sll_delete3(node *head, element  data)
{
    node *current = head;
    node *tmp = NULL;
    int status = 0;
    while (current->next) {
        if (current->next->data == data) {
        	tmp = current->next->next;
        	free(current->next);
            current->next = tmp ;
            status = 1;
            continue;
        }

        current = current->next;
    }

    if (1 == status)
        return 1;
    return 0;
}

/*
** function  : sll_delete_head
** author	 : hongsmallgod
** brief     : 删除单链表第一个节点(首元结点)
** argument  : @head: 链表头结点指针
** return 	 : 1:删除成功; 0: 链表为空
*/
int sll_delete_head(node *head)
{
    if (NULL == head->next)
        return 0;
    node *tmp = head->next->next;
    free(head->next);
    head->next = tmp;
    return 1;
}

/*
** function  : sll_delete_tail
** author    : hongsmallgod
** brief     : 删除单链表最后一个节点(尾结点)
** argument  : @head: 链表头结点指针
** return    : 1:删除成功; 0: 链表为空
*/
int sll_delete_tail(node *head)
{
    node *current = head;
    if (NULL == head->next)
        return 0;
    for (; current->next->next; current = current->next);
    free(current->next);
    current->next = NULL;
    return 1;
}
#if 0
/*
** function  : create_sll
** author    : hongsmallgod
** brief     : 创建单链表, 无序
** argument  : void
** return    : NULL:内存不足; else: 链表头节点指针
*/
node *create_sll(void)
{
    int data = -1;
    /*
    ** 创建头节点
    */
    node *head = (node *)malloc(sizeof(node));
    if (NULL == head)
            return NULL;
    head->data = 0;
    head->next = NULL;

    while (scanf("%d", &data) == 1 && data != -1) {
       sll_insert3(head, data);
    }
    return head;
}
#endif
/*
** function  : sll_destroy
** author	 : hongsmallgod
** brief     : 销毁单链表
** argument  : 链表头节点指针
** return 	 : none
*/
void sll_destroy(node *head)
{
    node *tmp;
    node *current = head;

    while (current) {
        tmp = current->next;
        free(current);
        current = tmp;
    }
}

/*
** function  : get_sll_node_num
** author	 : hongsmallgod
** brief     : 获取单链表节点数
** argument  : @head: 链表头结点指针
** return 	 : @count: 节点数
*/
size_t get_sll_node_num(node *head)
{
    int count = 0;
    node *current = head;
    while (current->next) {
        count++;
        current = current->next;
    }
    return count;
}
#if 0
/*
** function  : sll_sort
** author	 : hongsmallgod
** brief     : 单链表排序函数(冒泡法)
** argument  : @head: 链表头结点指针
** return 	 : none
*/
void sll_sort(node *head)
{
    int num = get_sll_node_num(head);
    node *current = head->next;
    int flag;
    int tmp;
    if (num == 0)
        return;
    int k = num - 1;
    while (k) {
    	flag = 0;
        for (int i = 0; i < k; i++) {
            if (current->data > current->next->data) {
                tmp = current->data;
                current->data = current->next->data;
                current->next->data = tmp;
                flag = i;
            }
            current = current->next;
        }
        k = flag;
        current = head->next;
    }
}
endif
/*
** function  : sll_insert6
** author	 : hongsmallgod
** brief     : 单链表节点插入函数
** argument  : @rootp: 链表头指针的指针(链表头指针的地址); @data: 关键值
** return 	 : -1: 内存不足; 1:插入成功
*/
int sll_insert6(node **rootp, element  data)
{
    node *current;
    node *new = (node *)malloc(sizeof(node));
    if (NULL == new)
            return -1;
    new->data = data;

    while ((current = *rootp) && current->data < data)
        rootp = &current->next;

    *rootp = new;
    new->next = current;

    return 1;
}
/*
** function  : sll_get_head
** author    : hongsmallgod
** brief     : 获取单链表第一个元素
** argument  : @head: 链表头结点指针; @data: 数据指针
** return    : 1:获取成功; 0: 链表为空
*/
int sll_get_head(node *head, element *data)
{
    if (head->next == NULL)
        return 0;
    *data = head->next->data;
    return 1;
}

/*
** function  : sll_get_tail
** author    : hongsmallgod
** brief     : 获取单链表最后一个元素
** argument  : @head: 链表头结点指针; @data: 数据指针
** return    : 1:获取成功; 0: 链表为空
*/
int sll_get_tail(node *head, element *data)
{
    node *current = head->next;
    if (NULL == head->next)
        return 0;
    for (; current->next; current = current->next);
    *data = current->data;
    return 1;
}
/*
** function  : sll_get_and_delete_head
** author    : hongsmallgod
** brief     : 获取并删除单链表第一个元素
** argument  : @head: 链表头结点指针; @data: 数据指针
** return    : 1:获取成功; 0: 链表为空
*/
int sll_get_and_delete_head(node *head, element *data)
{
    if (NULL == head->next)
        return 0;
    node *tmp = head->next->next;
    *data = head->next->data;
    free(head->next);
    head->next = tmp;
    return 1;

}

/*
** function  : sll_get_and_delete_tail
** author    : hongsmallgod
** brief     : 获取并删除单链表最后一个元素
** argument  : @head: 链表头结点指针; @data: 数据指针
** return    : 1:获取成功; 0: 链表为空
*/
int sll_get_and_delete_tail(node *head, element *data)
{
    node *current = head;
    if (NULL == head->next)
        return 0;
    for (; current->next->next; current = current->next);
    *data = current->next->data;
    free(current->next);
    current->next = NULL;
    return 1;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值