写一个C语言的链表记录一下

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

// 节点结构体
struct Node
{
    int a;                                        // 数据位
    struct Node* pNext;                            // 地址位
};

// 全局和局部的区别
struct Node* g_pHead = NULL;                    // 头指针
struct Node* g_pEnd = NULL;                        // 尾指针

// 函数声明
void AddListTill(int a);                        // 创建一个链表,在链表中添加数据(尾添加)可以用于队列
void AddListHead(int a);                        // 创建一个链表,在链表中添加数据(头添加)可以用于栈
void DeleteHead();                                // 头删除
void DeleteTill();                                // 尾删除
void ScanList();                                // 遍历链表(查1个 或者全查)
struct Node* SelectNode(int a);                    // 查询指定节点
void FreeList();                                // 链表清空
void FreeRandNode(int a);                        // 删除指定节点
void AddListRand(int index, int a);                // 指定位置插入节点

int main(void) {
    g_pHead;
    AddListTill(1);
    AddListTill(2);
    AddListTill(3);
    AddListTill(4);
    AddListHead(0);
    ScanList();                                    // 01234

    AddListRand(1,1);        
    ScanList();                                    // 011234
    DeleteHead();    
    ScanList();                                    // 11234
    DeleteTill();
    //ScanList();                                    // 1123

    struct Node* pFind; 
    pFind = SelectNode(2);
    if (pFind != NULL) {
        printf("find num : %d\n", pFind->a);
    }
    else {
        printf("find nothing\n");
    }

    FreeRandNode(2);
    ScanList();                                    // 1134

    system("pause");
    return 0;
}

void AddListTill(int a) {

    // 创建一个节点
    struct Node* pTmep = (struct Node*)malloc(sizeof(struct Node));

    // 节点数据赋值
    pTmep->a = a;
    pTmep->pNext = NULL;

    // 将节点链接到我的链表中
    if (NULL == g_pEnd || NULL == g_pHead) {
        g_pHead = pTmep;
    }
    else {
        g_pEnd->pNext = pTmep;
    }
    g_pEnd = pTmep;
}

void AddListHead(int a) {

    // 创建一个节点
    struct Node* pTmep = (struct Node*)malloc(sizeof(struct Node));

    // 节点数据赋值
    pTmep->a = a;
    pTmep->pNext = NULL;

    // 将节点链接到我的链表中
    if (NULL == g_pEnd || NULL == g_pHead) {
        g_pHead = pTmep;
        g_pEnd = pTmep;
    }
    else {
        pTmep->pNext = g_pHead;
        g_pHead = pTmep;
    }
}

void ScanList() {
    struct Node* pTemp = g_pHead;        // 定义一个中间变量指向头部为了防止改变原来的链表

    // bool类型 !pTemp  
    while (pTemp != NULL) {
        printf("  %d   ", pTemp->a);
        pTemp = pTemp->pNext;
    }
    printf("\n");
}

struct Node* SelectNode(int a)
{
    struct Node* pTemp = g_pHead;        

    while (pTemp != NULL) {
        if (a == pTemp->a) {
            return pTemp;
        }
        pTemp = pTemp->pNext;
    }

    return NULL;
}

void FreeList() {
    struct Node* pTemp = g_pHead;

    while (pTemp != NULL) {
        struct Node* pt = pTemp;
        pTemp = pTemp->pNext;
        free(pt);
    }

    // 一定记得要初始化方便下次操作
    g_pHead = NULL;
    g_pEnd = NULL;
}

void FreeRandNode(int a) {
    if (NULL == g_pHead) {
        printf("链表为空,无需释放!!\n");
    }

    struct Node* pTemp = SelectNode(a);
    if (NULL == pTemp) {
        printf("没有这个节点\n");
        return;
    }
    // 一个节点
    if (g_pEnd == g_pHead) {
        DeleteHead();
    }
    // 两个节点
    else if (g_pHead->pNext == g_pEnd) {
        if (g_pHead == pTemp) {
            DeleteHead();
        }
        else if (g_pEnd == pTemp) {
            DeleteTill();
        }
    }
    // 多个节点
    else {
        if (g_pHead == pTemp) {
            DeleteHead();
        }
        else if (g_pEnd == pTemp) {
            DeleteTill();
        }
        else {
            // 找到要删除的前一个节点
            struct Node* pt= g_pHead;
            while (pt->pNext != pTemp)
            {
                pt = pt->pNext;
            }
            // 链接
            pt->pNext = pTemp->pNext;
            // 释放
            free(pTemp);
        }
    }
}

void DeleteHead() {
    if (NULL == g_pHead){
        printf("链表为空,无需释放!!\n");
    }
    // 记住旧的头
    struct Node* pTemp = g_pHead;
    // 下一个节点变成新的头
    g_pHead = g_pHead->pNext;
    // 释放旧的头
    free(pTemp);
}

void DeleteTill() {
    if (NULL == g_pEnd) {
        printf("链表为空,无需释放!!\n");
        return;
    }

    if (g_pHead == g_pEnd) {
        free(g_pHead);
        g_pEnd = NULL;
        g_pHead = NULL;
    }else{
        // 找尾巴前一个节点
        struct Node* pTemp = g_pHead;
        while (pTemp->pNext != g_pEnd) {
            pTemp = pTemp->pNext;
        }    
        // 释放尾巴
        free(g_pEnd);
        // 尾巴前移
        g_pEnd = pTemp;
        // 尾巴下一个为空
        g_pEnd->pNext = NULL;
    }
}

void AddListRand(int index, int a) {
    if (NULL == g_pHead) {
        printf("链表为空,无需释放!!\n");
        return;
    }
    struct Node* pt = SelectNode(index);
    if (NULL == pt) {
        printf("没有指定节点\n");
        return;
    }
    // 有节点创建新节点
    struct Node* pTmep = (struct Node*)malloc(sizeof(struct Node));

    pTmep->a = a;
    pTmep->pNext = NULL;

    // 链接到链表
    if (pt == g_pEnd) {
        g_pEnd->pNext = pTmep;
        g_pEnd = pTmep;
    }
    else {
        // 先连
        pTmep->pNext = pt->pNext;

        // 后断
        pt->pNext = pTmep;
    }
}

猜你喜欢

转载自www.cnblogs.com/fanhua666/p/12906393.html
今日推荐