没有头结点的单链表[c语言实现]

#include <stdio.h>
#include <stdlib.h>

/*
 * 单链表是线性表链式存储的一种,其储存不连续。
 * 单链表的数据结构中包含两个变量:数据和指向下一结点的指针。
 * 一个结点只知道他的下一个结点的地址。
 * 一个单链表必须有一个头指针指向该单链表中的第一个结点,否则链表会在内存中丢失。
 */

typedef int ElementData;

typedef struct node{
    ElementData data;
    struct node* next;
} Node, *LinkedList;

//************************************************ 函数声明列表 ************************************************
/* 1、链表初始化 得到没有头结点的空链表 */
LinkedList init();
/* 2、输出链表的内容 */
void displayList(LinkedList list);
/* 3、向链表头部插入新结点 */
LinkedList insert(LinkedList list, ElementData data);
/* 4、向链表的尾部插入新结点 */
LinkedList appendIn(LinkedList list, ElementData data);
/* 5、向链表中指定位置插入数据 */
LinkedList insertPos(LinkedList list, int pos, ElementData data);
/* 6、在查找的数据之后插入一个结点 */
LinkedList insertData(LinkedList list, ElementData find, ElementData data);
/* 7、在链表中查找指定索引位置的元素 */
LinkedList findByIndex(LinkedList list, int index);
/* 8、在链表中查找指定数据的元素的位置 */
int findByData(LinkedList list, ElementData data);
/* 9、在链表中查找指定数据的元素 */
LinkedList findByNode(LinkedList list, ElementData data);
/* 10、删除链表第一个结点 */
LinkedList removeFirst(LinkedList list);
/* 11、删除链表最后一个元素 */
LinkedList removeLast(LinkedList list);
/* 12、删除指定索引位置的结点 */
LinkedList removeByIndex(LinkedList list, int index);
/* 13、删除指定值的结点 */
LinkedList removeByData(LinkedList list, ElementData data);
/* 14、清空链表 */
LinkedList clear(LinkedList list);
//************************************************ 函数声明列表 ************************************************


/**
 * 测试程序入口
 *
 * @return int
 */
int main() {
    //初始化链表
    LinkedList list = init();
    displayList(list);

    // 向链表头部插入数据
    list = insert(list, 1);
    list = insert(list, 2);
    displayList(list);

    // 向链表的尾部插入数据
    list = appendIn(list, 3);
    list = appendIn(list, 4);
    list = appendIn(list, 9);
    displayList(list);

    // 查找指定索引位置上的元素
    LinkedList found = findByIndex(list, 0);
    if (found != NULL) {
        printf("索引为0的元素是 %d\n", found->data);
    } else {
        printf("没有找到索引为0的元素\n");
    }

    found = findByIndex(list, 3);
    if (found != NULL) {
        printf("索引为3的元素是 %d\n", found->data);
    } else {
        printf("没有找到索引为3的元素\n");
    }

    // 向链表指定位置插入元素
    list = insertPos(list, 2, 5);
    displayList(list);

    list = insertPos(list, 1, 6);
    displayList(list);

    list = insertPos(list, 7, 7);
    displayList(list);

    list = insertPos(list, 12, 25);
    displayList(list);

    // 按数据查找返回索引
    int index = findByData(list, 2);
    if (list != NULL) {
        printf("保存数据 2 的结点首次出现的索引是 %d\n", index);
    } else {
        printf("保存数据 2 的结点没有找到\n");
    }

    // 安数据查找返回结点
    Node *foundNode = findByNode(list, 2);
    if (foundNode != NULL) {
        printf("保存数据 2 的结点的下一个结点保存的数据是%d\n", foundNode->next->data);
    } else {
        printf("保存数据 2 的结点没有找到\n");
    }

    // 在查找到的数据结点后插入新数据
    list = insertData(list, 5, 8);
    displayList(list);

    // 删除索引是0的元素
    list = removeByIndex(list, 0);
    displayList(list);
    // 删除索引是2的元素 8
    list = removeByIndex(list, 2);
    printf("删除索引是2的元素后:\n");
    displayList(list);

    // 删除链表第一个元素
    list = removeFirst(list);
    displayList(list);
    // 删除链表最后一个元素
    list = removeLast(list);
    displayList(list);

    // 使用索引删除
    list = removeByIndex(list, 1);
    printf("删除链表中索引为 1 的结点后:\n");
    displayList(list);

    // 使用值搜索删除
    list = removeByData(list, 2);
    displayList(list);
    list = removeByData(list, 3);
    displayList(list);
    list = removeByData(list, 7);
    displayList(list);

    // 清理链表
    list = clear(list);
    displayList(list);

    return 0;
}

/**
 * 链表初始化 得到没有头结点的空链表
 *
 * @return  List
 */
LinkedList init() {

    return NULL;
}


/**
 * 输出链表的内容
 *
 * @param list
 */
void displayList(LinkedList list) {
    if (list == NULL) {
        printf("链表是空的!\n");
    } else {
        Node* cur = list;
        while (cur != NULL) {
            printf("%d \t", cur->data);
            cur = cur->next;
        }
        printf("\n");
    }
}


/**
 * 向链表的头部插入新结点
 *
 * @param list
 * @param data
 * @return  LinkedList
 */
LinkedList insert(LinkedList list, ElementData data) {
    Node *tmp = (Node *) malloc(sizeof(Node));
    Node *head = list;
    if (tmp == NULL) {
        printf("插入新结点失败\n");
        return head;
    } else {
        tmp->data = data;
        tmp->next = head;
        head = tmp;

        return head;
    }
}


/**
 * 向链表的尾部插入新结点
 *
 * @param list
 * @param data
 * @return
 */
LinkedList appendIn(LinkedList list, ElementData data) {
    Node *head, *cur;
    head = cur = list;

    // 新结点
    Node *tmp = (Node *) malloc(sizeof(Node));
    tmp->data = data;
    tmp->next = NULL;

    // 链表为空时处理方式
    if (cur == NULL) {
        head = tmp;
        return head;
    }

    // 移动指针到链表最后一个元素
    while (cur->next != NULL) {
        cur = cur->next;
    }
    cur->next = tmp;

    return head;
}


/**
 * 在链表中查找指定索引位置的元素
 *
 * @param list  list
 * @param index int
 * @return  LinkedList
 */
LinkedList findByIndex(LinkedList list, int index) {
    Node *cur = list;
    if (cur == NULL) {
        printf("链表为空\n");
        return NULL;
    }
    if (index < 0) {
        printf("索引不能小于0");
        return NULL;
    }

    int i = 0;
    while (cur!=NULL && i < index) {
        cur = cur->next;
        i++;
    }

    return cur;
}


/**
 * 在链表中查找指定数据的元素的位置(首次找到即返回)
 *
 * @param list  LinkedList
 * @param data  ElementData
 * @return  LinkedList
 */
int findByData(LinkedList list, ElementData data) {
    Node *cur = list;
    if (cur == NULL) {
        printf("链表为空\n");
        return -1;
    }

    int i = 0;
    while (cur != NULL) {
        if (cur->data == data) {
            return i;
        } else {
            cur = cur->next;
        }
        i++;
    }

    printf("没有找到需要的数据\n");
    return -1;
}


/**
 * 在链表中查找指定数据的元素的位置(首次找到即返回)
 *
 * @param list  LinkedList
 * @param data  ElementData
 * @return  LinkedList
 */
LinkedList findByNode(LinkedList list, ElementData data) {
    Node *cur = list;
    if (cur == NULL) {
        printf("链表为空\n");
        return NULL;
    }

    while (cur != NULL) {
        if (cur->data == data) {
            return cur;
        }
        cur = cur->next;
    }

    printf("没有找到需要的数据\n");
    return NULL;
}

/**
 * 向链表中指定位置插入数据
 *
 * @param list  LinkedList
 * @param pos   int
 * @param data  ElementData
 * @return  LinkedList
 */
LinkedList insertPos(LinkedList list, int pos, ElementData data) {
    Node *head = list;
    Node *cur = list;

    if (cur == NULL) {
        printf("链表不能为空\n");
        return 0;
    }
    if (pos < 1) {
        printf("插入位置不能小于1\n");
        return 0;
    }

    Node *tmp = (Node *) malloc(sizeof(Node));
    tmp->data = data;

    if (pos == 1) {
        tmp->next = cur;
        head = tmp;
    } else {
        Node *found = findByIndex(head, (pos-1) - 1); // 插入位置的前一个元素
        if (found == NULL) {
            printf("指定位置超过链表长度\n");
            return head;
        }
        tmp->next = found->next;
        found->next = tmp;
    }

    return head;
}


/**
 * 在指定的数据后面插入一个新节点
 *
 * @param list  LinkedList
 * @param find  ElementData
 * @param data  ElementData
 * @return  LinkedList
 */
LinkedList insertData(LinkedList list, ElementData find, ElementData data) {
    Node *head;
    head = list;
    if (head == NULL) {
        printf("链表为空,无法进行操作\n");
        return head;
    }

    Node *found = findByNode(head, find);
    if (found == NULL) {
        printf("没有找到保存数据 %d 的结点,插入失败", find);
        return head;
    }

    // 找到后正常插入
    Node *tmp = (Node *) malloc(sizeof(Node));
    tmp->data = data;
    tmp->next = found->next;
    found->next = tmp;

    return head;
}


/**
 * 删除链表第一个结点
 *
 * @param list  LinkedList
 * @return  LinkedList
 */
LinkedList removeFirst(LinkedList list) {
    Node *head = list;
    Node *tmp = NULL;
    if (head == NULL) {
        printf("链表为空,删除失败\n");
        return head;
    }

    tmp = head;
    head = head->next;
    free(tmp);

    return head;
}


/**
 * 删除链表最后一个元素
 *
 * @param list
 * @return
 */
LinkedList removeLast(LinkedList list) {
    Node *head = list;
    Node *cur = list;
    Node *tmp = NULL;
    if (cur == NULL) {
        printf("链表为空,删除失败\n");
        return head;
    }
    if (cur->next == NULL) {
        tmp = cur->next;
        head = tmp;
        free(tmp);

        return head;
    }

    // cur移动到指向倒数第二个结点
    while (cur->next->next != NULL) {
        cur = cur->next;
    }

    tmp = cur->next;
    cur->next = NULL;
    free(tmp);

    return head;
}


/**
 * 删除指定位置的结点
 *
 * @param list
 * @param index
 * @return
 */
LinkedList removeByIndex(LinkedList list, int index) {
    Node *head = list;
    Node *tmp = NULL;
    if (head == NULL) {
        printf("链表为空,没有元素可以删除\n");
        return head;
    }

    if (index == 0) {
        tmp = head;
        head = head->next;
    } else {
        LinkedList found = findByIndex(head, index - 1);
        if (found == NULL) {
            printf("索引超过了最大可用值\n");
            return head;
        }
        tmp = found->next;
        found->next = found->next->next;
    }

    free(tmp);
    return head;
}


/**
 * 删除指定值的结点
 *
 * @param list
 * @param data
 * @return
 */
LinkedList removeByData(LinkedList list, ElementData data) {
    Node *head = list;
    Node *tmp = NULL;
    if (head == NULL) {
        printf("链表为空,没有元素可以删除\n");
        return head;
    }

    int index = findByData(list, data);
    if (index < 0) {
        printf("没有找到要删除的元素\n");
        return head;
    } else if (index == 0) {
        tmp = head;
        head = head->next;
    } else {
        LinkedList found = findByIndex(head, index - 1);
        if (found == NULL) {
            printf("没有找到要查出的元素\n");
            return head;
        }
        tmp = found->next;
        found->next = found->next->next;
    }

    free(tmp);
    return head;
}


/**
 * 清空链表
 *
 * @param list
 * @return
 */
LinkedList clear(LinkedList list) {
    Node *cur = list;

    int i = 1;
    while (cur != NULL) {
        cur = removeFirst(cur);
        printf("删除第%d个元素成功\t", i);
        i++;
    }
    printf("\n");

    return NULL;
}
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值