单向链表程序

 

/*****************************************************************************
*                                    程序说明
*            程序名称:简单单向链表
*
*            功能:    实现单向链表的创建、插入、删除、遍历和查找
*
*            作者:    Veis
*
*            注:此代码已在VC6.0及VS2010环境下编译通过,能正常实现所对应的功能
*            程序元素排序与数组下标一样,从0开始。
******************************************************************************/
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>

//宏定义数组大小,便于修改
#define N 10        

struct student
{
    char name[20];                //数据域
    struct student *next;        //指针域
};
//判断查找和删除时对应位置的内容是否为空
bool judge(struct student *p, int position)
{
    int count;
    
    //初始化很重要
    count = 0;

    while( NULL != p )
    {
        p = p->next;
        count++;
    }
    //    printf("count:%d
",count);
    if( position > (count - 1) )
    {
        return false;
    }else 
    {
        return true;
    }
}
//创建链表
struct student * create()
{
    // head链表的头指针,即链表的首地址
    // current当前处理的元素
    //next下一个状态的指针
    struct student *current, *head, *next;
    char str[N];
    char flag;
    
    //提示用户输入信息
    printf("请输入学生姓名:
");
    scanf("%s",str);
    
    //动态申请内存
    head = (struct student *)malloc(sizeof(struct student));
    //字符串之间不能直接复制,需要调用字符串处理函数strcpy,包含在库string.h
    strcpy( head->name , str );

    //把链表的头指针赋给当前状态指针
    current = head;
    
    //输入y/n
    printf("是否继续输入?");
    scanf("%s",&flag);

    //排除回车符的干扰
    getchar();            

    while(flag != 'n')
    {
        //提示用户输入信息
        printf("请输入学生姓名:
");
        scanf("%s",str);

        //动态申请内存
        next = (struct student *)malloc(sizeof(struct student));
        
        //判断是否分配内存成功
        if( NULL == next )
        {
            printf("Error:内存分配失败!");
            //退出程序,作用和 return 相似
            exit(-1);        
        }
        strcpy( next->name , str );

        //把当前状态指针的下一个指向下一个链表
        current->next = next;

        //把当前状态指针指往后移一个
        current = next;
    
        printf("是否继续输入?");
        scanf("%s",&flag);

        //排除回车符的干扰
        getchar();    
    }

    //输入完成后把当前状态指针的下一个状态指向NULL
    current->next = NULL;

    return head;
}

// 遍历链表
void list(struct student *p)
{
    while(1)
    {
        printf("%s 
", p->name);

        if( p->next != NULL )
        {
            p = p->next;
        }else
        {
            break;
        }
    }
}

//插入元素到链表
void insert(struct student *p)
{
    // insert要插入的元素
    // current当前处理的元素
    struct student *insert, *current;
    char str[N];
    int position;

    current = p;

    printf("请输入需要插入的学生姓名:
");
    scanf("%s",str);
    
    //动态申请内存
    insert = (struct student *)malloc(sizeof(struct student));

    //判断是否分配内存成功
    if( NULL == insert )
    {
        printf("Error:内存分配失败!");
        exit(-1);
    }
    strcpy( insert->name , str );
loop:
    printf("请输入需要插入的位置:
");
    scanf("%d",&position);

    
    //查询并判断元素插入位置
    if( position > 0 )
    {
        while( position > 1 )
        {
            current = current->next;
            position--;
        }
        //插入的元素指向当前元素的下一个
        insert->next = current->next;

        //当前元素的下一个指向插入的元素
        current->next = insert;
    }
    else if( position == 0 ) 
    {
        p = insert;
        insert->next = current;
    }
    else 
    {
        printf("
Error:输入错误!
");
        goto loop;
    }
    list(p);
}
//删除链表元素
void delet(struct student *p)
{
    // insert用来保存要删除的元素
    // current当前处理的元素
    struct student *current, *delet;
    int position;

    current = p;
    delet = current;
loop:
    printf("请输入需要删除的位置:
");
    scanf("%d",&position);
    
    if( judge(p,position) == true)
    {
        if( position > 0 )
        {
            while( position > 1 )
            {
                current = current->next;
                position--;
            }
            //记录删除的节点
            delet = current->next;

            //使当前指针指向下一个状态
            current->next = delet->next;

            //释放要删除的内存
            free(delet);
        
        }else if( position == 0 )
        {
            //使当前指针直接指向下一个节点
            p = current->next;

            //释放内存
            free(current);
        }
        else 
        {
            printf("
Error:输入错误!
");
            goto loop;
        }
        //调用查看效果
        list(p);
    }else 
    {
        printf("
Error:输入错误!
");
        goto loop;
    }
}

//回显查找的元素,可用于以后的拓展,故写成一个函数
void display(struct student *p)
{
    printf("%s 
", p->name);
}

//查找元素
void search(struct student *p)
{
    struct student *current;
    int position;
    
    current = p;
loop:
    printf("请输入需要查找的位置:
");

    scanf("%d",&position);
    if( judge(p,position) == true)
    {
        //根据输入查找对应位置
        if( position > 0 )
        {
            while( position > 1 )
            {
                current = current->next;
                position--;
            }

            p = current->next;

        }else if( position == 0 )
        {
            p = current;
        }
        else 
        {
            printf("Error:输入错误!");
            goto loop;
        }
        //显示查找的内容
        display(p);
    }else
    {
        printf("
Error:输入错误!
");
        goto loop;
    }
}
void main()
{
    struct student *p;

    //创建链表
    p = create();

    //删除链表
//    delet(p);

    //插入元素
//    insert(p);

    //查找元素
    search(p);
}

查找功能效果如下图所示:

原文地址:https://www.cnblogs.com/veis/p/7066366.html