无头结点无环的单链表实现

//linklist.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linklist.h"

#define TESTHEADER printf("\n============%s=========", __FUNCTION__)

//初始化链表
void LinkListInit(LinkNode** phead) {
    if (phead == NULL) {
        return;
    }
    *phead = NULL;
}

//LinkListInit的测试代码
void TestPrintChar(LinkNode* phead, char* msg) {
    printf("%s\n", msg);
    if (phead == NULL) {
        return;
    }
    LinkNode* cur = phead;
    for (; cur != NULL; cur = cur->next) {
        printf("[%c | %p] ->", cur->data, cur->next);
    }
    printf("\n");
}


//创建一个新结点
LinkNode* LinkNodeCreate(LinkNodeType value) {
    LinkNode* new_node = (LinkNode*)malloc(sizeof(LinkNode));
    new_node->data = value;
    new_node->next = NULL;
}

//销毁一个结点
void LinkNodeDestroy(LinkNode** phead) {
    free(*phead);
    *phead = NULL;
}

//尾插一个元素

void LinkListPushBack(LinkNode** phead, LinkNodeType value) {
    if (phead == NULL) {
        return;//非法输入
    }
    if (*phead == NULL) {
        LinkNode* new_node = LinkNodeCreate(value);
        *phead = new_node;
        return;
    }
    LinkNode* cur = *phead;
    for (; cur->next != NULL; cur = cur->next) {
    }
    LinkNode* new_node = LinkNodeCreate(value);
    cur->next = new_node;
}

//尾删一个元素
void  LinkListPopBack(LinkNode** phead) {
    if (phead == NULL) {
        return;//非法输入
    }
    if (*phead == NULL) {
        return;//空链表
    }
    LinkNode* cur = *phead;
    if (cur->next == NULL) {//只有一个结点
        LinkNodeDestroy(phead);
        return;
    }
    for (; cur->next->next != NULL; cur = cur->next) {
    }
    LinkNodeDestroy(&(cur->next));
}

//头插
void LinkListPushFront(LinkNode** phead, LinkNodeType value) {
    if (phead == NULL) {
        return;//非法输入
    }
    if (*phead == NULL) {
        LinkListPushBack(phead, value);
        return;
    }
    LinkNode* new_head= LinkNodeCreate(value);
    new_head->next = *phead;
    *phead = new_head;
}


//LinkListPushFront测试代码
void TestPushFront() {
    TESTHEADER;
    LinkNode* head;
    LinkListInit(&head);
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'b');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    TestPrintChar(head, "头插四个元素");
}

//头删
void LinkListPopFront(LinkNode** phead) {
    if (phead == NULL) {
        return;//非法输入
    }
    if (*phead == NULL) {
        return;//空链表
    }
    if ((*phead)->next == NULL) {
        LinkListPopBack(phead);
        return;
    }
    LinkNode* new_head = *phead;
    *phead = new_head->next;
    LinkNodeDestroy(&new_head);
}

//LinkListPopFront测试代码
void TestPopFront() {
    TESTHEADER;
    LinkNode* head;
    LinkListInit(&head);
    LinkListPopFront(&head);
    TestPrintChar(head, "头删空链表");

    LinkListPushFront(&head, 'a');
    TestPrintChar(head, "头插一个元素");
    LinkListPopFront(&head);
    TestPrintChar(head, "头删一个元素");
}

//查找指定元素(to_find)
LinkNode* LinkListFind(LinkNode* phead, LinkNodeType to_find){
    if (phead == NULL){
        return NULL;//非法输入
    }
    LinkNode* cur = phead;
    for (; cur != NULL; cur = cur->next){
        if (cur->data == to_find){
            return cur;
        }
    }
    return NULL;
}

//LinkListFind测试代码
void TestFind()
{
    TESTHEADER;
    LinkNode* head;
    LinkListInit(&head);
    LinkListPushFront(&head, 'b');
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'e');
    LinkListPushFront(&head, 'f');
    LinkNode* ret = LinkListFind(head, 'a');
    TestPrintChar(head, "头插六个元素");
    printf("&a = %p\n", ret);
}

//在指定位置元素(pos)前插入新元素(value)
void LinkListInsert(LinkNode** phead, LinkNode* pos, LinkNodeType value){
    if (phead == NULL){
        return;//非法输入
    }
    if (*phead == NULL || (*phead)->next == NULL){
        LinkListPushFront(phead, value);
        return;
    }
    LinkNode* cur = *phead;
    LinkNode* new_node = LinkNodeCreate(value);
    while (1)
    {
        if (cur->next == pos){
            new_node->next = pos;
            cur->next = new_node;
            return;
        }
        cur = cur->next;
    }
}

//LinkNodeInsert测试代码
void TestInsert()
{
    TESTHEADER;
    LinkNode* head;
    LinkListInit(&head);
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'e');
    LinkListPushFront(&head, 'f');
    LinkListInsert(&head, head->next, '1');
    TestPrintChar(head, "往e前面插入元素‘1’:");
}

//在指定位置元素(pos)后插入一个新元素(value)
void LinkListInsertAfter(LinkNode** phead, LinkNode* pos, LinkNodeType value){
    if (phead == NULL){
        return;//非法输入
    }
    if (*phead == NULL){
        LinkListPushBack(phead, value);
        return;
    }

    LinkNode* new_node = LinkNodeCreate(value);
    new_node->next = pos->next;
    pos->next = new_node;
}

//LinkListInsertAfter测试代码
void TestInsertAfter()
{
    TESTHEADER;
    LinkNode* head;
    LinkListInit(&head);
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'e');
    LinkListPushFront(&head, 'f');
    LinkListInsertAfter(&head, head->next->next, '1');
    TestPrintChar(head, "往d后面插入元素‘1’:");
}

//删除指定位置(pos)元素
void LinkListEraser(LinkNode** phead, LinkNode* pos){
    if (phead == NULL || pos == NULL){
        return;//非法输入
    }
    if (*phead == NULL){
        return;//链表为空
    }
    if ((*phead)->next == NULL){
        LinkNodeDestroy(phead);
        return;
    }
    LinkNode* cur = *phead;
    while (cur->next != pos){
        cur = cur->next;
    }
    LinkNode* to_eraser = cur->next;
    LinkNodeDestroy(&pos);
    cur->next = to_eraser->next;
}

//LinkListEraser测试代码

void TestEraser(){
    LinkNode* head;
    LinkListInit(&head);
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'e');
    LinkListPushFront(&head, 'f');
    TestPrintChar(head, "头插5个元素:");
    LinkListEraser(&head, head->next);
    TestPrintChar(head, "删除e:");
}

//不遍历在指定位置前插入一个元素
void LinkNodeInsertBefor(LinkNode** phead, LinkNode* pos, LinkNodeType value){
    if (phead == NULL || pos == NULL){
        return;//非法输入
    }
    if (*phead == NULL){
        LinkListPushFront(phead, value);
        return;
    }
    LinkNode* new_node = LinkNodeCreate(value);
    new_node->data = pos->data;
    pos->data = value;
    new_node->next = pos->next;
    pos->next = new_node;
}

//LinkNodeInsertBefor测试代码

void TestInsertBefor(){
    TESTHEADER;
    LinkNode* head;
    LinkListInit(&head);
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'e');
    LinkListPushFront(&head, 'f');
    LinkListInsert(&head, head->next, '1');
    TestPrintChar(head, "往e前面插入元素‘1’:");
}

//删除指定值元素
void LinkListRemove(LinkNode** phead, LinkNodeType to_delete){
    if (phead == NULL){
        return;//非法输入
    }
    if (*phead == NULL){
        return;//链表为空
    }
    LinkNode* cur;
    cur = *phead;
    while (cur != NULL){
        if (cur->data == to_delete){
            break;
        }
        cur = cur->next;
    }
    if (cur == NULL){
        return;
    }
    LinkListEraser(phead, cur);
    return;
}

//LinkListRemove测试代码
void TestRemove(){
    TESTHEADER;
    LinkNode* head;
    LinkListInit(&head);
    LinkListInit(&head);
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'e');
    LinkListPushFront(&head, 'f');
    TestPrintChar(head, "插入5个元素:");
    LinkListRemove(&head, 'e');
    TestPrintChar(head, "删除‘e’:");
}

//删除指定值所有元素

void LinkListRemoveAll(LinkNode** phead, LinkNodeType value){
    if (phead == NULL){
        return;//非法输入
    }
    if (*phead == NULL){
        return;//链表为空
    }
    LinkNode* cur = *phead;
    while (cur != NULL){
        if (cur->data == value){
            LinkListRemove(phead, value);
        }
        cur = cur->next;
    }
}

//LinkListRemove测试代码
void TestRemoveAll(){
    TESTHEADER;
    LinkNode* head;
    LinkListInit(&head);
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    TestPrintChar(head, "插入9个元素");
    LinkListRemoveAll(&head, 'a');
    TestPrintChar(head, "删除链表中的'a':");
}

//链表元素和
size_t LinkNodeSize(LinkNode* phead){
    if (phead == NULL){
        return 0;
    }
    int count = 0;
    LinkNode* cur = phead;
    for (; cur != NULL; cur = cur->next){
        count++;
    }
    return count;
}

//LinkNodeSize测试代码
void TestSize(){
    LinkNode* head;
    LinkListInit(&head);
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    LinkListPushFront(&head, 'a');
    LinkListPushFront(&head, 'c');
    LinkListPushFront(&head, 'd');
    int count = 0;
    count = LinkNodeSize(head);
    printf("expected count = %d, actuall count = %d\n", 9, count);
}


int main() {
    TestCreat();
    TestPushFront();
    TestPopFront();
    TestFind();
    TestInsert();
    TestInsertAfter();
    TestEraser();
    TestInsertBefor();
    TestRemove();
    TestRemoveAll();
    TestSize();
    return 0;
}

//linklist.h
#pragma once

typedef char LinkNodeType;

typedef struct LinkNode {
    LinkNodeType data;
    struct LinkNode* next;
}LinkNode;

typedef LinkNode* PLinkNode;

void LinkListInit(LinkNode** phead);

void LinkListPushBack(LinkNode** phead, LinkNodeType value);

LinkNode* LinkNodeCreate(LinkNodeType value);

void LinkListPopFront(LinkNode** phead);

void LinkListPushFront(LinkNode** phead, LinkNodeType value);

void LinkListPopBack(LinkNode** phead);

void LinkNodeDestroy(LinkNode** phead);

LinkNode* LinkListFind(LinkNode* phead, LinkNodeType to_find);

void LinkListInsert(LinkNode** phead, LinkNode* pos, LinkNodeType value);

void LinkListInsertAfer(LinkNode** phead, LinkNode* pos, LinkNodeType value);

void LinkListInsertBefor(LinkNode** phead, LinkNode* pos, LinkNodeType value);

void LinkListEraser(LinkNode** phead, LinkNode* pos);

void LinkListRemove(LinkNode** phead, LinkNodeType to_delet);

void LinkListRemoveAll(LinkNode** phead, LinkNodeType value);

void LinkListSize(LinkNode* phead);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值