zoukankan      html  css  js  c++  java
  • C语言数据结构_单链表_19个功能实现全解

    基本说明

    代码来自于网上,自己实现的功能就是基础链表的插入删除修改节点,而这份代码比较具有较好的代码习惯,比较详细,所以记录下来。

    链表是最简单的数据结构,实现原理也比简单,了解了原理,基本也没什么内容;

    程序C实现

    // 原文地址 http://www.cnblogs.com/renyuan/archive/2013/05/21/3091506.html  
    /*在原文的基础上面做了以下补充,现在可以实现全部功能了*/
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    typedef int elemType;//定义存入的数据的类型可以是int char 
    
    typedef struct NODE{ //定义链表的结构类型
        elemType element;
        struct NODE *next;
    }Node;
    
    /************************************************************************/
    /*             以下是关于线性表链接存储(单链表)操作的19种算法        */
    
    /* 1.初始化线性表,即置单链表的表头指针为空 */
    /* 2.创建线性表,此函数输入负数终止读取数据*/
    /* 3.打印链表,链表的遍历*/
    /* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
    /* 5.返回单链表的长度 */
    /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
    /* 7.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行 */
    /* 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */
    /* 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */
    /* 10.向单链表的表头插入一个元素 */
    /* 11.向单链表的末尾添加一个元素 */
    /* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */
    /* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
    /* 14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行 */
    /* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
    /* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
    /* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
    /* 18.交换2个元素的位置 */
    /* 19.将线性表进行冒排序 */
    
    /*注意检查分配到的动态内存是否为空*/
    
    
    /* 1.初始化线性表,即置单链表的表头指针为空 */
    void initList(Node **pNode)
    {
        *pNode=NULL;
        printf("initList函数执行,初始化成功
    ");
    }
    
    /* 2.创建线性表,此函数输入负数终止读取数据*/
    Node *creatList(Node *pHead)
    {
        Node *p1,*p2;
        p1=p2=(Node *)malloc(sizeof(Node));
        if(p1 == NULL || p2 ==NULL)
        {
            printf("内存分配失败
    ");    
            exit(0);
        }
        memset(p1,0,sizeof(Node));
    
        scanf("%d",&p1->element);
        p1->next=NULL;
    
        while(p1->element >0)  //输入的值大于0则继续,否则停止
        {
            if(pHead == NULL)//空表,接入表头
            {
                pHead=p1;
            }
            else 
            {
                p2->next=p1;
            }
    
            p2=p1;
            p1=(Node *)malloc(sizeof(Node));
    
            if(p1==NULL||p2==NULL)
            {
                printf("内存分配失败
    ");
                exit(0);
            }
            memset(p1,0,sizeof(Node));
            scanf("%d",&p1->element);
            p1->next=NULL;
        }
        printf("CreatList函数执行,链表创建成功
    ");
        return pHead;    
    }
    
    /* 3.打印链表,链表的遍历*/
    void printList(Node *pHead)
    {
        if(NULL==pHead)
        {
            printf("PrintList函数执行,链表为空
    ");
        }
        else
        {
            while(NULL!=pHead)
            {
                printf("%d
    ",pHead->element);
                pHead=pHead->next;
            }
        }
    
    }
    
    
    /* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
    void clearList(Node *pHead)
    {
        Node *pNext;
    
        if(pHead==NULL)
        {
            printf("clearList函数执行,链表为空
    ");
            return;
        }
        while(pHead->next!=NULL)
        {
            pNext=pHead->next;
            free(pHead);
            pHead=pNext;
        }
        printf("clearList函数执行,链表已经清除!
    ");
    
    }
    
    /* 5.返回链表的长度*/
    int sizeList(Node *pHead)
    {
        int size=0;
    
        while(pHead!=NULL)
        {
            size++;
            pHead=pHead->next;
        }
        printf("sizelist函数执行,链表长度为%d
    ",size);
        return size;
    }
    
    /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
    int isEmptyList(Node *pHead)
    {
        if(pHead==NULL)
        {
            printf("isEmptylist函数执行,链表为空!
    ");
            return 1;
        }
    
        else 
            printf("isEmptylist函数执行,链表非空!
    ");
            return 0;
    
    }
    
    /* 7.返回链表中第post节点的数据,若post超出范围,则停止程序运行*/
    int getElement(Node *pHead,int pos)
    {
        int i=0;
        if(pos<1)
        {
            printf("getElement函数执行,pos值非法!");
            return 0;
        }
        if(pHead==NULL)
        {
            printf("getElement函数执行,链表为空!");
        }
    
        while (pHead!=NULL)
        {
            ++i;
            if(i==pos)
            {
                break;
            }
            pHead=pHead->next;
        }    
        if(i<pos)
        {
            printf("getElement函数执行,pos值超出链表长度
    ");
            return 0;        
        }
        printf("getElement函数执行,位置%d中的元素为%d
    ",pos,pHead->element);
    
        return 1;
    }
    
    //8.从单一链表中查找具有给定值x的第一个元素,若查找成功后,返回该节点data域的存储位置,否则返回NULL
    elemType *getElemAddr(Node *pHead,elemType x)
    {
        if(NULL==pHead)
        {    
            printf("getEleAddr函数执行,链表为空");
            return NULL;    
        }
        if(x<0)
        {
            printf("getEleAddr函数执行,给定值x不合法
    ");
            return NULL;
        }
        while((pHead->element!=x)&&(NULL!=pHead->next))//判断链表是否为空,并且是否存在所查找的元素
        {
            pHead=pHead->next;
        }    
        if(pHead->element!=x)
        {
            printf("getElemAddr函数执行,在链表中没有找到x值
    ");
            return NULL;
        }
        else
        {
            printf("getElemAddr函数执行,元素%d的地址为0x%x
    ",x,&(pHead->element));
        }
        return &(pHead->element);
    
    }    
    
    
    /*9.修改链表中第pos个点X的值,如果修改成功,则返回1,否则返回0*/
    int modifyElem(Node *pNode,int pos,elemType x)
    {
        Node *pHead;
        pHead=pNode;
        int i=0;
        if(NULL==pHead)
        {
            printf("modifyElem函数执行,链表为空
    ");
            return 0;
        }
    
        if(pos<1)
        {
            printf("modifyElem函数执行,pos值非法
    ");
            return 0;
        }
    
        while(pHead!= NULL)
        {
            ++i;
            if(i==pos)
            {
                break;
            }
            pHead=pHead->next;
        }
    
        if(i<pos)
        {
            printf("modifyElem函数执行,pos值超出链表长度
    ");
            return 0;
        }
        pNode=pHead;
        pNode->element=x;
        printf("modifyElem函数执行,修改第%d点的元素为%d
    ",pos,x);
    
        return 1;
    
    }
    
    /* 10.向单链表的表头插入一个元素 */
    int insertHeadList(Node **pNode,elemType insertElem)
    {
        Node *pInsert;
        pInsert=(Node *)malloc(sizeof(Node));
        if(pInsert==NULL)  exit(1);
        memset(pInsert,0,sizeof(Node));
        pInsert->element=insertElem;
        pInsert->next=*pNode;
        *pNode=pInsert;
        printf("insertHeadList函数执行,向表头插入元素%d成功
    ",insertElem);
        return 1;
    }
    
    /* 11.向单链表的末尾添加一个元素 */
    int insertLastList(Node *pNode,elemType insertElem)
    {
        Node *pInsert;    
        Node *pHead;
        Node *pTmp;
    
        pHead=pNode;
        pTmp=pHead;
        pInsert=(Node *)malloc(sizeof(Node));
        if(pInsert==NULL)  exit(1);
        memset(pInsert,0,sizeof(Node));
        pInsert->element=insertElem;
        pInsert->next=NULL;
        while(pHead->next!=NULL)
        {
            pHead=pHead->next;
        }
        pHead->next=pInsert;      
        printf("insertLastList函数执行,向表尾插入元素%d成功!
    ",insertElem);
        return     1;
    }
    
    /* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0*/ 
    int isAddPos(Node *pNode,int pos,elemType x)
    {
        Node *pHead;
        pHead=pNode;
        Node *pTmp;
        int i=0;
    
        if(NULL==pHead)
        {
            printf("AddPos函数执行,链表为空
    ");
            return 0;
        }
    
        if(pos<1)
        {
            printf("AddPos函数执行,pos值非法
    ");
            return 0;
        }
    
        while(pHead!=NULL)
        {
            ++i;
            if(i==pos)
            break;
            pHead=pHead->next;
        }
    
        if(i<pos)
        {
            printf("AddPos函数执行,pos值超出链表长度
    ");
            return 0;
        }
    
        pTmp=(Node *)malloc(sizeof(Node));
        if(pTmp==NULL)  exit(1);
        memset(pTmp,0,sizeof(Node));
        pTmp->next=pHead->next;
        pHead->next=pTmp;
        pTmp->element=x;
    
        printf("AddPos函数执行成功,向节点%d后插入数值%d
    ",pos,x);
        return 1;
    }
    
    /* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
    int OrrderList(Node *pNode,elemType x)
    {
    //注意如果此数值要排到行尾要修改本代码
        Node *pHead;
            pHead=pNode;
            Node *pTmp;
    
            if(NULL==pHead)
            {
                    printf("OrrderList函数执行,链表为空
    ");
                    return 0;
            }
    
            if(x<1)
            {
                    printf("OrrderList函数执行,x值非法
    ");
                    return 0;
            }
    
            while(pHead!=NULL)
            {
                    if((pHead->element)>=x)
                    break;
                    pHead=pHead->next;
            }
    
    
        if(pHead==NULL)   
        {
            printf("OrrderList函数查找完毕,该函数中没有该值
    ");
            return 0;
        }    
    
    
        pTmp=(Node *)malloc(sizeof(Node));
        if(pTmp==NULL)  exit(1);       
        memset(pTmp,0,sizeof(Node));
            pTmp->next=pHead->next;
            pHead->next=pTmp;
            pTmp->element=x;
    
        printf("OrrderList函数成功插入数值%d
    ",x);
        return 1;
    }
    
    /*14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行*/
    int DelHeadList(Node **pList)
    {
        Node *pHead;
        pHead=*pList;
        if(pHead!=NULL)
        printf("DelHeadList函数执行,函数首元素为%d删除成功
    ",pHead->element);
        else 
        {
            printf("DelHeadList函数执行,链表为空!");
            return 0;
        }
        *pList=pHead->next;
        return 1;
    }
    
    /* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
    int DelLastList(Node *pNode)
    {    
        Node *pHead;
        Node *pTmp;
    
        pHead=pNode;
        while(pHead->next!=NULL)
        {
            pTmp=pHead;
            pHead=pHead->next;
        }
        printf("链表尾删除元素%d成功!
    ",pHead->element);
        free(pHead);
        pTmp->next=NULL;
        return     1;
    }
    
    /* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
    int DelPos(Node *pNode,int pos)
    {
        Node *pHead;
        pHead=pNode;
        Node *pTmp;
    
        int i=0;
    
        if(NULL==pHead)
        {
            printf("DelPos函数执行,链表为空
    ");
            return 0;
        }
    
        if(pos<1)
        {
            printf("DelPos函数执行,pos值非法
    ");
            return 0;
        }
    
        while(pHead!=NULL)
        {
            ++i;
            if(i==pos)
            break;
            pTmp=pHead;
            pHead=pHead->next;
        }
    
        if(i<pos)
        {
            printf("DelPos函数执行,pos值超出链表长度
    ");
            return 0;
        }
            printf("DelPos函数执行成功,节点%d删除数值%d
    ",pos,pHead->element);
        pTmp->next=pHead->next;
        free(pHead);    
        return 1;
    }
    
    /* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
    int Delx(Node **pNode,int x)
    {
        Node *pHead;
        Node *pTmp;
        pHead=*pNode;
        int i=0;
    
        if(NULL==pHead)
        {    
            printf("Delx函数执行,链表为空");
            return 0;    
        }
        if(x<0)
        {
            printf("Delx函数执行,给定值x不合法
    ");
            return 0;
        }
        while((pHead->element!=x)&&(NULL!=pHead->next))//判断链表是否为空,并且是否存在所查找的元素
        {
            ++i;
            pTmp=pHead;    
            pHead=pHead->next;
        }    
        if(pHead->element!=x)
        {
            printf("Delx函数执行,在链表中没有找到x值
    ");
            return 0;
        }
        if((i==0)&&(NULL!=pHead->next))
        {
            printf("Delx函数执行,在链表首部找到此元素,此元素已经被删除
    ");
            *pNode=pHead->next;
            free(pHead);
            return 1;
        }
        printf("Delx函数执行,首个为%d元素被删除
    ",x);
        pTmp->next=pHead->next;
        free(pHead);
        return 1;
    }
    
    /* 18.交换2个元素的位置 */
    int exchange2pos(Node *pNode,int pos1,int pos2)
    {
        Node *pHead;
        int *pTmp;
        int *pInsert;
        int a;
        int i=0;
    
        if(pos1<1||pos2<1)
            {
                    printf("DelPos函数执行,pos值非法
    ");
                    return 0;
            }
    
        pHead=pNode;
            while(pHead!=NULL)
            {
                    ++i;
                    if(i==pos1)
                    break;
                    pHead=pHead->next;
            }
    
            if(i<pos1)
            {
                    printf("DelPos函数执行,pos1值超出链表长度
    ");
                    return 0;
            }
    
        pTmp=&(pHead->element);
        i=0;
        pHead=pNode;
            while(pHead!=NULL)
            {
                    ++i;
                    if(i==pos2)
                    break;
                    pHead=pHead->next;
            }
    
            if(i<pos2)
            {
                    printf("DelPos函数执行,pos2值超出链表长度
    ");
                    return 0;
            }
    
        pInsert=&(pHead->element);
        a=*pTmp;
        *pTmp=*pInsert;
        *pInsert=a;
    
        printf("DelPos函数执行,交换第%d个和第%d个pos点的值
    ",pos1,pos2);
            return 1;
    }
    
    int swap(int *p1,int *p2)
    {
        int a;
        if(*p1>*p2)
        {
            a=*p1;
            *p1=*p2;
            *p2=a;
        }
        return 0;
    }
    
    /* 19.将线性表进行冒泡排序 */
    int Arrange(Node *pNode)
    {
        Node *pHead;
            pHead=pNode;
    
        int a=0,i,j;
    
            if(NULL==pHead)
            {
                     printf("Arrange函数执行,链表为空
    ");
                     return 0;
            }
    
        while(pHead!=NULL)
        {
            ++a;
                pHead=pHead->next;
            }
    
        pHead=pNode;
        for(i=0;i<a-1;i++)
        {
            for(j=1;j<a-i;j++)
            {
                swap(&(pHead->element),&(pHead->next->element));
                pHead=pHead->next;
            }
            pHead=pNode;
        }
        printf("Arrange函数执行,链表排序完毕!
    ");
        return 0;
    }
    
    int main()
    {
        Node *pList=NULL;
        int length=0;
    
        elemType posElem;
    
        initList(&pList);
        printList(pList);
    
        pList=creatList(pList);
        printList(pList);
    
        sizeList(pList);
        printList(pList);
    
        isEmptyList(pList);
    
    
            posElem=getElement(pList,3);
        printList(pList);
    
        getElemAddr(pList,5);
    
        modifyElem(pList,4,1);
        printList(pList);
    
        insertHeadList(&pList,5);
        printList(pList);
    
        insertLastList(pList,10);
        printList(pList);
    
        isAddPos(pList,4,5);
        printList(pList);
    
        OrrderList(pList,6);
        printList(pList);
    
        DelHeadList(&pList);    
        printList(pList);
    
        DelLastList(pList);
        printList(pList);
    
        DelPos(pList,5);
        printList(pList);
    
        Delx(&pList,5);
        printList(pList);
    
        exchange2pos(pList,2,5);
        printList(pList);
    
        Arrange(pList);    
        printList(pList);
    
        clearList(pList);
        return 0;
    }
  • 相关阅读:
    Vue日期转化
    javascript数组去重
    javascript数组及类数组详解
    javascript的argument和克隆方法详解
    javascript中对this的理解
    javascript命名空间及对象枚举的理解
    javascript继承模式详解
    javascript的call和apply区别
    javascript原型及原型链详解
    javascript对象及包装类
  • 原文地址:https://www.cnblogs.com/actanble/p/6713434.html
Copyright © 2011-2022 走看看