编辑代码

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

//构建typedef
typedef struct Node
{
    int data;// 数据域
    struct Node*pNext; //指针域
}NODE,*PNODE; //NODE 等价于 struct Node , PNODE 等价于 struct Node * ;

//函数声明区域
PNODE create_list(void);
void traverse_list(PNODE);
bool is_empty(PNODE);
int length_list(PNODE);
void sort_list(PNODE);
bool insert_list(PNODE,int,int);
bool delete_list(PNODE,int,int*);

//主函数运行区域
int main (void) 
{
    int val; //存放删除的节点数据
    PNODE pHead = NULL; //等价于 struct Node * pHead = NULL
    pHead = create_list(); //创建一个非循环单链表 并且把该链表的头结点的地址附给pHead
    traverse_list(pHead); //遍历链表,将其内容输出
/*    if(is_empty(pHead))  //链表是否为空
        printf("链表为空\n");
    else
        printf("链表不空\n");
*/
    int len = length_list(pHead); //输出链表的长度
    printf("链表的长度为: %d  \n" ,len);
    sort_list(pHead);
    traverse_list(pHead);
    //insert_list(pHead,1,100);
    if(delete_list(pHead,1,&val))
    {
        printf("删除成功 您删除的元素是: %d\n",val);
        printf("\n");
    }
    else
    {
        printf("删除失败\n");
    }
    traverse_list(pHead);
    return 0;
} 


//构建函数区域
//动态创建一个链表
PNODE create_list(void)
{
    int len; //存放有效节点个数
    int i; //计数
    int val; //存放用户输入的值
    

    PNODE pHead = (PNODE)malloc(sizeof(NODE)); //动态分配一个头结点,头结点不存放有效数据
    if(NULL == pHead)
    {
        printf("分配失败,程序终止!\n");
        exit(-1);
    }

    PNODE pTail = pHead; //定义了一个尾节点 以为暂时没有创建其他的节点 目前节点为 0 所以头结点就是尾节点
    pTail->pNext = NULL; //尾节点的指针域要为空

    printf("请输入您需要生成的链表节点的个数: len = ");
    scanf("%d",&len);

    for(i=0;i<len;++i)
    {
        printf("请输入第%d 个节点的值",i+1);
        scanf("%d",&val);
        PNODE pNew = (PNODE)malloc(sizeof(NODE)); //动态创建一个结点
        if(NULL == pNew)
        {
            printf("分配失败,程序终止!\n");
            exit(-1);
        }
        pNew->data = val; //把值附到新节点的数据域中
        pTail->pNext = pNew; //把新生成的节点挂到最后一个节点后面
        pNew->pNext = NULL; //新生成节点挂到最后一个节点后 作为尾节点指针域需要清空
        pTail = pNew; //将尾节点更新 以便于下一个节点挂上来
    }
    return pHead;
}

//遍历输出一个链表
void traverse_list(PNODE pHead)
{
    PNODE p = pHead->pNext; //将头指针的指针域附给 p (为什么不是将pHead附给p 因为若该链表为0长度时则没有pHead为NULL)
    while(NULL!=p) //最后一节点(尾节点)的数据域为 NULL
    {
        printf("%d\n",p->data); //输出该节点的数据
        p=p->pNext; //指向下一个节点的指针域,不能使用p++
    }
    printf("\n");
    return;
}

//判断链表是否为空
bool is_empty(PNODE pHead)
{
    if(NULL==pHead->pNext) //头结点指向首节点为空
    {
        return true;
    }
        return false;
}

//求链表的长度 和遍历输出类似 将输出语句改为 len++就行
int length_list(PNODE pHead)
{
    int len=0;
    PNODE p=pHead->pNext; //将头指针的指针域附给 p (为什么不是将pHead附给p 因为若该链表为0长度时则没有pHead为NULL)
    while(NULL != p) //最后一节点(尾节点)的数据域为 NULL
    {
        len++; //节点数自加
        p=p->pNext; //指向下一节点的指针域,不能用 p++
    }
    return len; //将len的值传回
}

//对链表排序
//参考数组的排序;
    void sort_list(PNODE pHead)
    {
        int i,j,t;
        int len=length_list(pHead);
        PNODE p,q;
        for(i=0,p=pHead->pNext;i<len-1;++i,p=p->pNext)
        {
            for(j=i+1,q=p->pNext;j<len;++j,q=q->pNext)
            {
                if(p->data > q->data)
                {
                    t = p->data;
                    p->data = q->data;
                    q->data = t;
                }
            }
        }
        return;
    }

//在链表中插入元素
bool insert_list(PNODE pHead,int pos,int val)
{
    int i=0;
    PNODE p=pHead; // p是指向头结点的指针

    while(NULL != p && i<pos-1) //在遍历链表时用一个变量++然后和要插入的位置pos进行比较
    {
        p=p->pNext; //下一个节点的指针域.不能用p++
        ++i; //节点数自增
    }
    if(i > pos-1||NULL == p) //插入的位置不能大于链表节点数,或者插入到空的链表里面(空链表不允许插入)
    return false;

    PNODE pNew = (PNODE)malloc(sizeof(NODE)); //动态分配了一个节点 地址附给 pNew
    if(NULL == pNew)
    {
        printf("动态内存分配失败,程序终止!\n");
        exit(-1);
    }
    pNew->data = val; //把需要插入的值挂上去
    PNODE q = p->pNext; //新建一个 q 指向 p 头结点后面一个节点
    p->pNext = pNew; //把需要插入的节点挂到头结点后面 (头结点指针域指向了 新建的节点)
    pNew->pNext = q; //新建的节点指针域指向 之前 头结点的后面一个节点 (新的节点插入完成)
    return true;    // 头结点和后面一个节点代表的是相对位置(即相对于插入点前面一个和后面一个节点)  
}

//删除一个节点
bool delete_list (PNODE pHead,int pos ,int * pVal)
{
    int i=0;
    PNODE p = pHead; //将头节点保存到p

    //遍历直到找到要删除节点的前一个节点
    while(NULL != p->pNext && i<pos-1)
    {
        p=p->pNext;
        ++i;
    }
    if(i>pos-1||NULL==p->pNext)
    return false;

    PNODE q = p->pNext; //新建一个q 指向删除的节点
    *pVal = q->data; //将要删除的数据保存到 pVal
    //删除p节点后面的节点 ==(q指向的节点)
    p->pNext = p->pNext->pNext;
    free(q);
    q=NULL;
    return true;
}