actanble

导航

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函数执行,初始化成功\n");
}

/* 2.创建线性表,此函数输入负数终止读取数据*/
Node *creatList(Node *pHead)
{
    Node *p1,*p2;
    p1=p2=(Node *)malloc(sizeof(Node));
    if(p1 == NULL || p2 ==NULL)
    {
        printf("内存分配失败\n");    
        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("内存分配失败\n");
            exit(0);
        }
        memset(p1,0,sizeof(Node));
        scanf("%d",&p1->element);
        p1->next=NULL;
    }
    printf("CreatList函数执行,链表创建成功\n");
    return pHead;    
}

/* 3.打印链表,链表的遍历*/
void printList(Node *pHead)
{
    if(NULL==pHead)
    {
        printf("PrintList函数执行,链表为空\n");
    }
    else
    {
        while(NULL!=pHead)
        {
            printf("%d\n",pHead->element);
            pHead=pHead->next;
        }
    }

}


/* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
void clearList(Node *pHead)
{
    Node *pNext;

    if(pHead==NULL)
    {
        printf("clearList函数执行,链表为空\n");
        return;
    }
    while(pHead->next!=NULL)
    {
        pNext=pHead->next;
        free(pHead);
        pHead=pNext;
    }
    printf("clearList函数执行,链表已经清除!\n");

}

/* 5.返回链表的长度*/
int sizeList(Node *pHead)
{
    int size=0;

    while(pHead!=NULL)
    {
        size++;
        pHead=pHead->next;
    }
    printf("sizelist函数执行,链表长度为%d\n",size);
    return size;
}

/* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
int isEmptyList(Node *pHead)
{
    if(pHead==NULL)
    {
        printf("isEmptylist函数执行,链表为空!\n");
        return 1;
    }

    else 
        printf("isEmptylist函数执行,链表非空!\n");
        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值超出链表长度\n");
        return 0;        
    }
    printf("getElement函数执行,位置%d中的元素为%d\n",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不合法\n");
        return NULL;
    }
    while((pHead->element!=x)&&(NULL!=pHead->next))//判断链表是否为空,并且是否存在所查找的元素
    {
        pHead=pHead->next;
    }    
    if(pHead->element!=x)
    {
        printf("getElemAddr函数执行,在链表中没有找到x值\n");
        return NULL;
    }
    else
    {
        printf("getElemAddr函数执行,元素%d的地址为0x%x\n",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函数执行,链表为空\n");
        return 0;
    }

    if(pos<1)
    {
        printf("modifyElem函数执行,pos值非法\n");
        return 0;
    }

    while(pHead!= NULL)
    {
        ++i;
        if(i==pos)
        {
            break;
        }
        pHead=pHead->next;
    }

    if(i<pos)
    {
        printf("modifyElem函数执行,pos值超出链表长度\n");
        return 0;
    }
    pNode=pHead;
    pNode->element=x;
    printf("modifyElem函数执行,修改第%d点的元素为%d\n",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成功\n",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成功!\n",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函数执行,链表为空\n");
        return 0;
    }

    if(pos<1)
    {
        printf("AddPos函数执行,pos值非法\n");
        return 0;
    }

    while(pHead!=NULL)
    {
        ++i;
        if(i==pos)
        break;
        pHead=pHead->next;
    }

    if(i<pos)
    {
        printf("AddPos函数执行,pos值超出链表长度\n");
        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\n",pos,x);
    return 1;
}

/* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
int OrrderList(Node *pNode,elemType x)
{
//注意如果此数值要排到行尾要修改本代码
    Node *pHead;
        pHead=pNode;
        Node *pTmp;

        if(NULL==pHead)
        {
                printf("OrrderList函数执行,链表为空\n");
                return 0;
        }

        if(x<1)
        {
                printf("OrrderList函数执行,x值非法\n");
                return 0;
        }

        while(pHead!=NULL)
        {
                if((pHead->element)>=x)
                break;
                pHead=pHead->next;
        }


    if(pHead==NULL)   
    {
        printf("OrrderList函数查找完毕,该函数中没有该值\n");
        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\n",x);
    return 1;
}

/*14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行*/
int DelHeadList(Node **pList)
{
    Node *pHead;
    pHead=*pList;
    if(pHead!=NULL)
    printf("DelHeadList函数执行,函数首元素为%d删除成功\n",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成功!\n",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函数执行,链表为空\n");
        return 0;
    }

    if(pos<1)
    {
        printf("DelPos函数执行,pos值非法\n");
        return 0;
    }

    while(pHead!=NULL)
    {
        ++i;
        if(i==pos)
        break;
        pTmp=pHead;
        pHead=pHead->next;
    }

    if(i<pos)
    {
        printf("DelPos函数执行,pos值超出链表长度\n");
        return 0;
    }
        printf("DelPos函数执行成功,节点%d删除数值%d\n",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不合法\n");
        return 0;
    }
    while((pHead->element!=x)&&(NULL!=pHead->next))//判断链表是否为空,并且是否存在所查找的元素
    {
        ++i;
        pTmp=pHead;    
        pHead=pHead->next;
    }    
    if(pHead->element!=x)
    {
        printf("Delx函数执行,在链表中没有找到x值\n");
        return 0;
    }
    if((i==0)&&(NULL!=pHead->next))
    {
        printf("Delx函数执行,在链表首部找到此元素,此元素已经被删除\n");
        *pNode=pHead->next;
        free(pHead);
        return 1;
    }
    printf("Delx函数执行,首个为%d元素被删除\n",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值非法\n");
                return 0;
        }

    pHead=pNode;
        while(pHead!=NULL)
        {
                ++i;
                if(i==pos1)
                break;
                pHead=pHead->next;
        }

        if(i<pos1)
        {
                printf("DelPos函数执行,pos1值超出链表长度\n");
                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值超出链表长度\n");
                return 0;
        }

    pInsert=&(pHead->element);
    a=*pTmp;
    *pTmp=*pInsert;
    *pInsert=a;

    printf("DelPos函数执行,交换第%d个和第%d个pos点的值\n",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函数执行,链表为空\n");
                 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函数执行,链表排序完毕!\n");
    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;
}

posted on 2016-12-31 15:35  白于空  阅读(345)  评论(0编辑  收藏  举报