链表笔记——一个将所输入数字从小到大排序的程序题

程序为(与课本不同,稍有改动)

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

struct listNode {
    char data;
    struct listNode *nextPtr;
};

typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;

void insert (ListNodePtr *sPtr,char value);
char delete (ListNodePtr *sPtr,char value);
int isEmpty(ListNodePtr sPtr);
void printList(ListNodePtr currentPtr);
void instructions (void);

int main()
{
    ListNodePtr startPtr=NULL;
    char item;
    unsigned int choice;
    char mm;

    instructions();
    printf("%s","?");

    mm=getchar();
    while(getchar()!='\n')
            continue;
    choice=(unsigned int)mm-48;

    while(choice!=3){

        switch (choice) {
        case 1:
           printf("%s","Enter a character:");
            item=getchar();
            while(getchar()!='\n')
                    continue;
            insert(&startPtr,item);
            printList(startPtr);
            break;

        case 2:
            if(!isEmpty(startPtr)){
                printf("%s","Enter character to be delete: ");
                item=getchar();
                while(getchar()!='\n')
                        continue;

                if(delete(&startPtr,item)){
                    printf("%c deleted.\n",item);
                    printList(startPtr);
                }else
                {
                    printf("%c not found.\n\n",item);
                }
            }
            else{
                puts("List is empty.");
            }
            break;

        default:
            puts("Invallid choice .\n");
            instructions();
            break;
        }
        printf("%s\n","?");
        mm=getchar();
        while(getchar()!='\n')
                continue;
        choice=(unsigned int)mm-48;

    }
    puts("End of run.");
}

void instructions()
{
    puts("Enter your choice:\n"
         "    1 to insert an element into the list.\n"
         "    2 to delete an element from the list.\n"
         "    3 to end.");
}

void insert(ListNodePtr *sPtr,char value)
{
    ListNodePtr newPtr=malloc(sizeof (ListNode));

    if(newPtr != NULL){
        newPtr->data=value;
        newPtr->nextPtr=NULL;

        ListNodePtr previousPtr=NULL;
        ListNodePtr currentPtr=*sPtr;

        while(currentPtr != NULL && value >currentPtr->data){
            previousPtr=currentPtr;
            currentPtr=currentPtr->nextPtr;
        }

        if(previousPtr==NULL){
            newPtr->nextPtr=*sPtr;
            *sPtr=newPtr;
        }
        else {
            previousPtr->nextPtr=newPtr;
            newPtr->nextPtr=currentPtr;
        }
    }else{
        printf("%c not inserted.No memory available.\n",value);
    }
}

char delete (ListNodePtr *sPtr,char value)
{
    if(value==(*sPtr)->data){
        ListNodePtr tempPtr=*sPtr;
        *sPtr=(*sPtr)->nextPtr;
        free(tempPtr);
        return value;
    }
    else
    {
        ListNodePtr previousPtr=*sPtr;
        ListNodePtr currentPtr=(*sPtr)->nextPtr;

        while(currentPtr!=NULL&&value!=currentPtr->data)
        {
            previousPtr=currentPtr;
            currentPtr=currentPtr->nextPtr;
        }

        if(currentPtr!=NULL)
        {
            ListNodePtr tempPtr=currentPtr;
            previousPtr->nextPtr=currentPtr->nextPtr;
            free(tempPtr);
            return value;
        }
    }
}

int isEmpty(ListNodePtr sPtr){
    return sPtr==NULL;
}

void printList(ListNodePtr currentPtr)
{
    if(isEmpty(currentPtr)){
        puts("List is empty.");
    }else
    {
        puts("The list is :");

        while(currentPtr !=NULL)
        {
            printf("%c --> ",currentPtr->data);
            currentPtr = currentPtr->nextPtr;
        }

        puts("NULL\n");
    }
}

一.insert函数

insert函数共分为三部分
1.用malloc()抓取一个新节点
2.用while循环顺藤摸瓜摸到尾部的子节点
3.将1.抓取的节点连接到链表上

void insert(ListNodePtr *sPtr,char value)
{
    ListNodePtr newPtr=malloc(sizeof (ListNode));

    if(newPtr != NULL){
        newPtr->data=value;
        newPtr->nextPtr=NULL;

        ListNodePtr previousPtr=NULL;
        ListNodePtr currentPtr=*sPtr;

        while(currentPtr != NULL && value >currentPtr->data){
            previousPtr=currentPtr;
            currentPtr=currentPtr->nextPtr;
        }

        if(previousPtr==NULL){
            newPtr->nextPtr=*sPtr;
            *sPtr=newPtr;
        }
        else {
            previousPtr->nextPtr=newPtr;
            newPtr->nextPtr=currentPtr;
        }
    }else{
        printf("%c not inserted.No memory available.\n",value);
    }
}

malloc()函数负责在内存中抓取sizeof (ListNode)的空间。并定义成ListNode型;
sPtr保存所抓取的空间的地址。

ListNodePtr previousPtr=NULL;//创建一个ListNode型指针指向NULL
ListNodePtr currentPtr=*sPtr;//创建一个ListNode指向表头

while(currentPtr != NULL && value >currentPtr->data)
顺藤摸瓜找到表尾或者发现一个value应该在的位置(比如value为5,当发现currentPtr->data为6时,说明value所在的节点应该在currentPtr指向节点的前面,且在previousPtr指向节点的后面)

if(previousPtr==NULL)
如果此时是链表第一个节点,就将该节点的地址赋值给主函数的startPtr。
如果是找到了表尾或应该在的位置,将上一个节点指向新节点,将新节点指向下一个节点。

注:

至于为什么insert函数的形参为ListNodePtr *sPtr,我认为只有实参为&startPtr时,即(带&),才能在不返回值的情况下改变主函数的startPtr。
delete()函数同理。

二.delete函数

char delete (ListNodePtr *sPtr,char value)
{
    if(value==(*sPtr)->data){
        ListNodePtr tempPtr=*sPtr;
        *sPtr=(*sPtr)->nextPtr;
        free(tempPtr);
        return value;
    }
    else
    {
        ListNodePtr previousPtr=*sPtr;
        ListNodePtr currentPtr=(*sPtr)->nextPtr;

        while(currentPtr!=NULL&&value!=currentPtr->data)
        {
            previousPtr=currentPtr;
            currentPtr=currentPtr->nextPtr;
        }

        if(currentPtr!=NULL)
        {
            ListNodePtr tempPtr=currentPtr;
            previousPtr->nextPtr=currentPtr->nextPtr;
            free(tempPtr);
            return value;
        }
    }
}

delete函数共分为两部分
1.找到节点
2.删除节点

if(value==(*sPtr)->data)
是否头节点为所要找节点

while(currentPtr!=NULL&&value!=currentPtr->data)
没有找到或找到

ListNodePtr tempPtr=*sPtr;
//tempPtr指向要删除的节点
*sPtr=(*sPtr)->nextPtr;
//头指针指向第二个节点作为头节点
free(tempPtr);
//删除节点
return value;
//告诉主函数已删除

ListNodePtr tempPtr=currentPtr;
//tempPtr指向要删除的节点
previousPtr->nextPtr=currentPtr->nextPtr;
//上一个节点指向下下节点
free(tempPtr);
//删除节点
return value;
//告诉主函数已删除

如果未删除,函数默认返回0

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YunB西风英

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值