数据结构之链表的增删改查逆置及传统链表与非传统链表

本质:结构体是一种构造数据类型;
用途:把不同类型的数据组合成一个整体-------自定义数据类型。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

// 传统链表
typedef struct Node
{
    int data;
    struct Node *next;
}SLIST;

// 不包含 data
typedef struct myNode
{
    struct Node *next;
}myNode;
// 非传统链表 业务节点大小可以不一样 缺点是计算节点其他数据的偏移量复杂
typedef struct teacher
{
    int data;
    char name[64];
    char name2[128];
    struct Node node;
}teacher;
// 通用链表 企业链表
typedef struct teacher
{
    struct Node node;
    int data;
    char name[64];
    char name2[128];

}teacher;

void testAdv()
{
    teacher t1, t2, t3;
    t1.node.next = &(t2.node);
    t2.node.next = &(t3.node);
    t3.node.next = NULL;
}

SLIST *Create_SList();// 创建链表

int Create_SList2(SLIST **mypHead);// 创建链表  优化

int SList_Print(SLIST *pHead);// 遍历链表

int SList_NodeInsert(SLIST *pHead, int x, int y);// 插入值 在x之前插入y

int SList_NodeDel(SLIST *pHead, int y);

int SList_Reverse(SLIST *pHead);

int SList_Destory(SLIST *pHead);


// 1、不停的malloc新节点 pM = malloc()
// 2、新节点入链表   pCurrent->next = pM
// 3、让新节点变成当前节点   pCurrent = pM
SLIST *Create_SList()
{
    SLIST *pHead, *pM, *pCurrent;
    int data = 0;
    // 创建头节点并初始化
    pHead = (SLIST *)malloc(sizeof(SLIST));
    if(NULL == pHead)
    {
        return NULL;
    }
    pHead->data = 0;
    pHead->next = NULL;

    printf("\nPlease enter your data:");
    scanf("%d",&data);

    pCurrent = pHead;

    while(-1 != data)
    {
        // 创建业务节点并初始化
        pM = (SLIST *)malloc(sizeof(SLIST));
        if(NULL == pM)
        {
            return NULL;
        }
        pM->data = data;
        pM->next = NULL;

        // 新节点入链表
        pCurrent->next = pM;
        // 新节点变成当前节点
        pCurrent = pM;// 链表节点的尾部追加

        printf("\nPlease enter your data:");
        scanf("%d",&data);
    }

    return pHead;
}

// 函数一个入口 多个出口(return)
// 指针做函数参数
int Create_SList2(SLIST **mypHead)
{
    SLIST *pHead, *pM, *pCurrent;
    int data = 0;
    int ret = 0;
    // 创建头节点并初始化
    pHead = (SLIST *)malloc(sizeof(SLIST));
    if(NULL == pHead)
    {
        ret = -1;
        printf("func Create_SList2() error:%d \n",ret);
        goto END;
    }
    pHead->data = 0;
    pHead->next = NULL;

    printf("\nPlease enter your data:");
    scanf("%d",&data);

    pCurrent = pHead;

    while(-1 != data)
    {
        // 创建业务节点并初始化
        pM = (SLIST *)malloc(sizeof(SLIST));
        if(NULL == pM)
        {
            ret = -2;
            goto END;
        }
        pM->data = data;
        pM->next = NULL;

        // 新节点入链表
        pCurrent->next = pM;
        // 新节点变成当前节点
        pCurrent = pM;// 链表节点的尾部追加

        printf("\nPlease enter your data:");
        scanf("%d",&data);
    }
END:
    if(0 != ret)
    {
        SList_Destory(pHead);
    }
    else
    {
        *mypHead = pHead;
    }
    return ret;
}

int SList_Print(SLIST *pHead)
{
    SLIST *ptmp = NULL;
    if(NULL == pHead)
    {
        return -1;
    }

    ptmp = pHead->next;
    printf("\nbegin\t");
    while(ptmp)
    {
        printf("%d ",ptmp->data);
        ptmp = ptmp->next;
    }
    printf("\tend");
    return 0;
}
// 链表是单向的,当前节点的位置保存在前驱节点的NEXT中
int SList_NodeInsert(SLIST *pHead, int x, int y)
{
    SLIST *pM, *pCurrent, *pPre;
    int data;
    // 创建新的节点pM
    pM = (SLIST *)malloc(sizeof(SLIST));
    if(NULL == pM)
    {
        return -1;
    }
    pM->next = NULL;
    pM->data = y;
    //遍历链表
    pPre = pHead;
    pCurrent = pHead->next;

    while(pCurrent)
    {
        if(pCurrent->data == x)
        {
            break;
        }
        pPre = pCurrent;
        pCurrent = pCurrent->next;
    }
    // 让新节点链接后续链表
    pM->next = pPre->next;
    // 让前驱节点链接新节点
    pPre->next = pM;

    return 0;
}

int SList_NodeDel(SLIST *pHead, int y)
{
    SLIST *pCurrent, *pPre;

    // 初始化状态
    pPre = pHead;
    pCurrent = pHead->next;
    // 遍历链表
    while(NULL != pCurrent)
    {
        if(pCurrent->data == y)
        {
            break;
        }
        pPre = pCurrent;
        pCurrent = pCurrent->next;
    }

    // 删除操作
    if(NULL == pCurrent)
    {
        printf("Not found %d",y);
        return -1;
    }
    pPre->next = pCurrent->next;
    if(NULL != pCurrent)
    {
        free(pCurrent);
    }

    return 0;
}

int SList_Destory(SLIST *pHead)
{
    SLIST *tmp = NULL;

    if(NULL == pHead)
    {
        return -1;
    }

    while(pHead != NULL)
    {
        tmp = pHead->next;// 缓存头节点
        free(pHead);
        pHead = tmp;
    }

    return 0;
}

int SList_Reverse(SLIST *pHead)
{
    SLIST *p = NULL;// 前驱指针
    SLIST *q = NULL;// 当前指针
    SLIST *t = NULL;// 缓存的一个节点

    if(NULL == pHead || NULL == pHead->next || NULL == pHead->next->next)
    {
        return 0;
    }

    // 前驱节点
    //    p = pHead;
    //    q = pHead->next;
    p = pHead->next;
    q = pHead->next->next;
    // 一个一个节点的逆置
    while(q)
    {
        t = q->next; // 缓冲节点
        q->next = p;// 逆置
        p = q;// 让p下移一个节点
        q = t;
    }
    // 头节点变成尾部节点后置为NULL
    pHead->next->next = NULL;
    pHead->next = p;

    return 0;
}
int main()
{
    SLIST *pHead = NULL;
    int ret = 0;
    // 创建链表并打印新链表
    pHead = Create_SList();
    ret = SList_Print(pHead);
    // 插入节点并打印新链表
    ret = SList_NodeInsert(pHead, 20, 19);
    ret = SList_Print(pHead);
    // 删除节点并打印新链表
    ret = SList_NodeDel(pHead, 19);
    ret = SList_Print(pHead);
    // 逆置链表节点并打印
    ret = SList_Reverse(pHead);
    ret = SList_Print(pHead);
    // 销毁链表
    ret = SList_Destory(pHead);

    system("pause");
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_34624951/article/details/78089438