zoukankan      html  css  js  c++  java
  • 链表

    用C语言来实现一个单向链表的增、查、改、删。以及约瑟夫环,链表倒置,插入排序等

    #include <stdlib.h>
    #include <stdio.h>
    #include <stdbool.h>
    
    typedef int DataType;//一是表明该类型的特殊作用,二是将来有可能要改变这种类型(比如提高精度),可以统一修改
    
    typedef struct Node
    {
        DataType Data;
        struct Node *pNext;
    }LinkNode;
    
    typedef struct List
    {
        LinkNode *pHead;
        int      cLen;
    }LinkList;
    
    //判空函数
    bool isEmptyLinkList(LinkList *pList)
    {
        return pList->pHead == NULL;
    }
    
    //创建一个链表
    LinkList *createLinkList()
    {
        LinkList *pList = malloc(sizeof(LinkList));
        //为了解决C语言中NULL代指空指针存在的二义性问题,在C++11版本(2011年发布)中特意引入了
        //nullptr这一新的关键字来代指空指针
        if(NULL == pList)
        {
            perror("fail to create!");
        }
        pList->pHead = NULL;
        pList->cLen = 0;
        return pList;
    }
    
    //头插
    int insertHeadLinkList(LinkList *pList, DataType value)
    {
        LinkNode *pNew = malloc(sizeof(LinkNode));
        if(NULL == pNew)
        {
            perror("fail to create!");
            return -1;
        }
        pNew->Data = value;
        pNew->pNext = pList->pHead;
        pList->pHead = pNew;
        ++pList->cLen;
        return 0;
    }
    
    //尾插
    int insertTailLinkList(LinkList *pList, DataType value)
    {
        if(isEmptyLinkList(pList))
        {
            insertHeadLinkList(pList,value);
        }
        else
        {
            LinkNode *pNew = malloc(sizeof(LinkNode));
            if(NULL == pNew)
            {
                perror("fail to create!");
                return -1;
            }
            pNew->Data = value;
            pNew->pNext = NULL;
            LinkNode *pTemp = pList->pHead;
            while(pTemp->pNext != NULL)
            {
                pTemp = pTemp->pNext;
            }
            pTemp->pNext = pNew;
            ++pList->cLen;
    
        }
        return 0;
    }
    
    //头删
    int deleteHeadLinkList(LinkList *pList)
    {
        if(!isEmptyLinkList(pList))
        {
            LinkNode *pTemp = pList->pHead;
            pList->pHead = pTemp->pNext;
            free(pTemp);
            --pList->cLen;
        }
        return 0;
    }
    
    //尾删
    int deleteTailLinkList(LinkList *pList)
    {
        if(!isEmptyLinkList(pList))
        {
            if(1 == pList->cLen)
            {
                deleteHeadLinkList(pList);
            }
            else if(2 <= pList->cLen)
            {
                LinkNode *pTemp = pList->pHead;
                while(pTemp->pNext->pNext != NULL)
                {
                    pTemp = pTemp->pNext;
                }
                free(pTemp->pNext);
                pTemp->pNext = NULL;
                --pList->cLen;
            }
        }
        return 0;
    }
    
    //查找
    LinkNode *findLinkNode(LinkList *pList, DataType value)
    {
        if(!isEmptyLinkList(pList))
        {
            LinkNode *pTemp = pList->pHead;
            while(pTemp != NULL)
            {
                if(pTemp->Data == value)
                {
                    return pTemp;
                }
                pTemp = pTemp->pNext;
            }
            if(pTemp == NULL)
            {
                printf("no find!
    ");
            }
            return NULL;
        }
        else
        {
            printf("List is empty!
    ");
        }
        return NULL;
    }
    
    //修改链表数据
    int modifyLinkList(LinkList *pList, int oldValue, DataType newValue)
    {
        LinkNode *pTemp = findLinkNode(pList, oldValue);
        if(pTemp != NULL)
        {
            pTemp->Data = newValue;
            return 1;
        }
        return 0;
    }
    
    //打印链表中结点个数及各结点数据
    void showLinkList(LinkList *pList)
    {
        if(isEmptyLinkList(pList))
        {
            printf("Linklist is empty!
    ");
        }
        else
        {
            printf("Linklist's cLen:%d
    ",pList->cLen);
            LinkNode *pTemp = pList->pHead;
            printf("Linklist's data:");
            while(pTemp != NULL)
            {
                printf("%d ",pTemp->Data);
                pTemp = pTemp->pNext;
            }
            printf("
    ");
        }
    }
    
    //摧毁链表
    void destroyLinkList(LinkList **ppList)
    {
        if(isEmptyLinkList(*ppList))
        {
            free(*ppList);
        }
        else
        {
            while((*ppList)->pHead != NULL)
            {
                deleteHeadLinkList(*ppList);
            }
            free(*ppList);
            *ppList = NULL;
        }
    }
    
    
    //快慢指针法求链表的中间结点
    LinkNode *findMidLinkList(LinkList *pList)
    {
        LinkNode *pFast = pList->pHead;
        LinkNode *pSlow = pList->pHead;
        while(pFast != NULL)
        {     
            pFast = pFast->pNext;
            if(pFast == NULL)
            {
                break;
            }
            else
            {
                pFast = pFast->pNext;
                pSlow = pSlow->pNext;
            }
        }
        return pSlow;
    }
    
    //寻找链表倒数第K个数据
    LinkNode *FindLastKNode(LinkList *pList, DataType k)
    {
        LinkNode *pFast = pList->pHead;
        LinkNode *pSlow = pList->pHead;
        for(int i = 0;i < k;++i)
        {
            pFast = pFast->pNext;
        }
        while(pFast != NULL)
        {
            pFast = pFast->pNext;
            pSlow = pSlow->pNext;
        }
        return pSlow;
    }
    
    //判断链表是否为环形
    int isLoopLinkList(LinkList *pList)
    {
        LinkNode *pFast = pList->pHead;
        LinkNode *pSlow = pFast;
        while(pFast != NULL)
        {
            pFast = pFast->pNext;
            if(pFast == NULL)
            {
                return 0;
            }
            pFast = pFast->pNext;
            pSlow = pSlow->pNext;
            if(pFast == pSlow)
            {
                return 1;
            }
        }
        return 0;
    }
    
    //约瑟夫环
    LinkNode *joseF(LinkList *pList)
    {
        LinkNode *pTmpNode = pList->pHead;
        LinkNode *pPreNode = NULL;
        while(pList->cLen > 1)
        {
            pPreNode = pTmpNode;
            pTmpNode = pTmpNode->pNext->pNext;
            pPreNode = pPreNode->pNext;
            pPreNode->pNext = pTmpNode->pNext;
            free(pTmpNode);
            pTmpNode = pPreNode->pNext;
            --pList->cLen;
        }
        return pTmpNode;
    }
    
    //链表倒置
    void reverseLinkList(LinkList *pList)
    {
        LinkNode *pTmpNode = pList->pHead;
        LinkNode *pInsertNode = NULL;
        pList->pHead = NULL;
        while(pTmpNode != NULL)
        {
            pInsertNode = pTmpNode;
            pTmpNode = pTmpNode->pNext;
            pInsertNode->pNext = pList->pHead;
            pList->pHead = pInsertNode;
        }
    }
    
    //删除链表指定位置的结点
    int deleteKLinkList(LinkList *pList, DataType value)
    {
        if(isEmptyLinkList(pList))
        {
            return 0;
        }
        LinkNode *pTmpNode = pList->pHead;
        LinkNode *pPreNode = pList->pHead;
        while(pTmpNode != NULL)
        {
            if(pTmpNode->Data == value)
            {
                if(pTmpNode == pPreNode)
                {
                    pList->pHead = pPreNode->pNext;
                    free(pTmpNode);
                    pTmpNode = pList->pHead;
                    pPreNode = pList->pHead;
                }
                else
                {
                    pPreNode->pNext = pTmpNode->pNext;
                    free(pTmpNode);
                    pTmpNode = pPreNode->pNext;
                }
                --pList->cLen;
            }
            else
            {
                pPreNode = pTmpNode;
                pTmpNode = pTmpNode->pNext;
            }
        }
        return 1;
    }
    
    //插入排序
    int insertSortLinkList(LinkList *pList)
    {
        if(isEmptyLinkList(pList) || pList->cLen == 1)
        {
            return 0;
        }
        //将链表从第一个结点断开
        LinkNode *pTmpNode = pList->pHead->pNext;
        LinkNode *pInsertNode = NULL;
        pList->pHead->pNext = NULL;
        while(pTmpNode != NULL)
        {
            pInsertNode = pTmpNode;
            pTmpNode = pTmpNode->pNext;
            pInsertNode->pNext = NULL;
            if(pInsertNode->Data < pList->pHead->Data)
            {
                pInsertNode->pNext = pList->pHead;
                pList->pHead = pInsertNode;
            }
            else
            {
                LinkNode *pTemp = pList->pHead;
                while(pTemp!=NULL && pTemp->pNext!=NULL && pTemp->pNext->Data < pInsertNode->Data)
                {
                    pTemp = pTemp->pNext;
                }
                pInsertNode->pNext = pTemp->pNext;
                pTemp->pNext = pInsertNode;
            }
        }
        return 0;
    }
    
    //主函数
    int main(void)
    {
        LinkList *pList = NULL;
        pList = createLinkList();      //创建链表
        insertHeadLinkList(pList, 10); //插入数据
        insertTailLinkList(pList, 30);
        insertTailLinkList(pList, 20);
        insertTailLinkList(pList, 40);
        insertTailLinkList(pList, 60);
        insertTailLinkList(pList, 50);
        insertTailLinkList(pList, 70);
        insertTailLinkList(pList, 80);
        showLinkList(pList);
        deleteKLinkList(pList,20);
        showLinkList(pList);
        insertSortLinkList(pList);
        showLinkList(pList);
    //    reverseLinkList(pList);        //链表倒置
    //    showLinkList(pList);
    //    deleteTailLinkList(pList);     //删除尾部数据
    //    showLinkList(pList);
    //    deleteHeadLinkList(pList);     //删除头部数据
    //    showLinkList(pList);
    //    modifyLinkList(pList, 20, 50); //将链表中的第一个20修改为50
    //    showLinkList(pList);
    //    LinkNode *pTmp = NULL;
    //    pTmp = findLinkNode(pList, 30);//寻找链表中的30
    //    destroyLinkList(&pList);       //摧毁链表
    //    LinkNode *pFindMid = NULL;
    //    pFindMid = findMidLinkList(pList);
    //    printf("%d
    ",pFindMid->Data);
    //    LinkNode *pFindKLast = NULL;
    //    pFindKLast = FindLastKNode(pList, 3);
    //    printf("%d
    ",pFindKLast->Data);
        return 0;
    }
    

    再来一个双向链表

    #include <stdlib.h>
    #include <stdio.h>
    #include <stdbool.h>
    
    //双向链表
    typedef struct Student
    {
        int id;
        int score;
        char name[32];
    }DataTpye;
    
    typedef struct Node
    {
        DataTpye data;
        struct Node *pPre;//不能在typedef类型之前使用它,如 DouNode *pPre;
        struct Node *pNext;
    }DouNode;
    
    typedef struct List
    {
        int cLen;
        DouNode *pHead;
    }DouList;
    
    //创建双向链表
    DouList *createDouList()
    {
        DouList *pList = malloc(sizeof(DouList));
        if(pList == NULL)
        {
            perror("fail to create!");
        }
        pList->cLen = 0;
        pList->pHead = NULL;
        return pList;
    }
    
    //判空函数
    bool isEmptyDouList(DouList *pList)
    {
        return (pList->pHead == NULL);
    }
    
    //显示双向链表数据
    void showDouList(DouList *pList, int dir)
    {
        if(isEmptyDouList(pList))
        {
            return ;
        }
        DouNode *pTemp = pList->pHead;
        if(dir == 1)
        {
            printf("cLen's number:%d
    ",pList->cLen);
            while(pTemp != NULL)
            {
                printf("%s %d %d
    ", pTemp->data.name, pTemp->data.id, pTemp->data.score);
                pTemp = pTemp->pNext;
            }
        }
        else if(dir == 0)
        {
            printf("cLen's number:%d
    ",pList->cLen);
            while(pTemp->pNext != NULL)
            {
                pTemp = pTemp->pNext;
            }
            while(pTemp != NULL)
            {
                printf("%s %d %d
    ", pTemp->data.name, pTemp->data.id, pTemp->data.score);
                pTemp = pTemp->pPre;
            }
        }
        printf("
    ");
    }
    
    //头插
    int insertHeadDouNode(DouList *pList, DataTpye *pdata)
    {
        DouNode *pNew = malloc(sizeof(DouNode));  //必须得在堆区开辟空间
        memcpy(&pNew->data, pdata, sizeof(DataTpye));
    
        pNew->pPre = NULL;
        pNew->pNext = pList->pHead;
    
        if(pList->pHead != NULL)
        {
            pList->pHead->pPre = pNew;
        }
        pList->pHead = pNew;
        ++pList->cLen;
        return 1;
    }
    
    //尾插
    int insertTailDouNode(DouList *pList, DataTpye *pdata)
    {
        if(pList->pHead == NULL)
        {
            insertHeadDouNode(pList, pdata);
        }
        if(pList->cLen >= 1)
        {
            DouNode *pNew = malloc(sizeof(DouNode));
            memcpy(&pNew->data, pdata, sizeof(DataTpye));
            pNew->pNext = NULL;
            DouNode *pTemp = pList->pHead;
            while(pTemp->pNext != NULL)
            {
                pTemp = pTemp->pNext;
            }
            pTemp->pNext = pNew;
            pNew->pPre = pTemp;
            ++pList->cLen;
        }
        return 1;
    }
    
    //头删
    int deleteHeadNodList(DouList *pList)
    {
        if(!isEmptyDouList(pList))
        {
            DouNode *pTemp = pList->pHead;
            pList->pHead = pTemp->pNext;
            if(pTemp->pNext != NULL)
            {
                pTemp->pNext->pPre = NULL;
            }
            free(pTemp);
            --pList->cLen;
        }
        return 1;
    }
    
    //尾删
    int deleteTailNodList(DouList *pList)
    {
        if(isEmptyDouList(pList))
        {
            return 0;
        }
        if(pList->cLen == 1)
        {
            deleteHeadNodList(pList);
        }
        if(pList->cLen > 1)
        {
            DouNode *pTemp = pList->pHead;
            while(pTemp->pNext != NULL)
            {
                pTemp = pTemp->pNext;
            }
            pTemp->pPre->pNext = NULL;
            free(pTemp);
            --pList->cLen;
        }
        return 1;
    }
    
    //摧毁链表
    void destroyDouList(DouList **ppList)
    {
        if((*ppList)->pHead != NULL)
        {
            deleteHeadNodList(*ppList);
        }
        free(*ppList);
        *ppList = NULL;
    }
    
    int main(void)
    {
        DouList *pList = NULL;
        pList = createDouList();//创建链表
        DataTpye stu[3] = {{1, 99, "zhangsan"}, {2, 91, "lisi"}, {3, 92, "wangwu"}};
        insertHeadDouNode(pList, &stu[0]);
        insertHeadDouNode(pList, &stu[1]);
        insertTailDouNode(pList, &stu[2]);
        showDouList(pList, 1);
        deleteTailNodList(pList);
        deleteHeadNodList(pList);
        showDouList(pList, 1);
    }
    

  • 相关阅读:
    [转]Vetur can't find `tsconfig.json` or `jsconfig.json` in d:VueProjectsmyroute.
    疾病检验的概率的问题
    约束优化方法之拉格朗日乘子法与KKT条件
    GloVe与word2vec
    RNN、LSTM、GRU
    SVM 常见问题
    深度学习常用优化器算法Optimizer详解
    树模型-常见问题点
    leetcode 打家劫舍
    node 图片处理库 sharp
  • 原文地址:https://www.cnblogs.com/wsl540/p/13803779.html
Copyright © 2011-2022 走看看