数据结构线性表之单链表的基本操作及菜单应用(C程序实现)

//参考书是机械工业出版社的数据结构与算法分析(C语言描述);

//本程序是可移植性程序;

//能在Linux/Mac os/Windows下编译运行;

//若有不足之处请提出,博主会尽所能修改;

//若是对您有用的话请点赞收藏或分享给它人;

//未经允许严禁抄袭以及转载;

//源代码奉上,希望能够对您有所启发;

//----------------------------------------------------------------------------
//main.c

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "linkedlist.h"

int show_menu(void);                  //显示主菜单;
int get_first(void);                  //获取用户输入的第1个字符;
void eatline(void);                   //清空输入缓冲区;
elemtype input(void);                 //获取用户输入的数据元素;
void choice(int ch, linkedlist head); //操作链表中的数据元素;

int main(void)
{
    
    
    int ch;
    linkedlist list = init_list_head();

    while ((ch = show_menu()) != 'q')
    {
    
    
        choice(ch, list);
    }
    destroy_list(list);
    printf("本程序完成!\n");

    return 0;
}

int show_menu(void)
{
    
    
    int ch;

    puts("========================================");
    puts("a) 判断链表是否为空");
    puts("b) 查看链表数据元素个数");
    puts("c) 查找链表某数据是否存在");
    puts("d) 在头结点后插入新的数据元素");
    puts("e) 删除某个数据元素");
    puts("f) 遍历链表");
    puts("q) 退出本程序");
    puts("========================================");
    printf("请您输入选择:");
    ch = get_first();
    while (strchr("abcdefq", ch) == NULL)
    {
    
    
        printf("您的输入无效!请重新输入:");
        ch = get_first();
    }
    return ch;
}

int get_first(void)
{
    
    
    int ch;

    do
    {
    
    
        ch = tolower(getchar());
    } while (isspace(ch));
    eatline();

    return ch;
}

void eatline(void)
{
    
    
    while (getchar() != '\n')
        continue;
    return;
}

elemtype input(void)
{
    
    
    elemtype temp;

    printf("请您输入一个数据元素:");
    while (scanf("%d", &temp) != 1)
    {
    
    
        eatline();
        printf("数据无效!请重新输入:");
    }
    eatline();
    return temp;
}

void choice(int ch, linkedlist head)
{
    
    
    pnode *pos;
    elemtype val;

    switch (ch)
    {
    
    
    case 'a':
    {
    
    
        printf("链表%s!\n", list_is_empty(head) ? "为空" : "非空");
        break;
    }
    case 'b':
    {
    
    
        printf("链表中元素个数: %d个\n", list_length(head));
        break;
    }
    case 'c':
    {
    
    
        val = input();
        if (find(val, head))
        {
    
    
            printf("链表中存在元素%d\n", val);
        }
        else
        {
    
    
            printf("链表中不存在元素%d\n", val);
        }
        break;
    }
    case 'd':
    {
    
    
        val = input();
        insert(head, head, val);
        printf("在头结点后插入数据元素%d成功!\n", val);
        break;
    }
    case 'e':
    {
    
    
        val = input();
        if (cancel(head, val))
        {
    
    
            printf("删除数据元素%d成功!\n", val);
        }
        else
        {
    
    
            printf("链表中不存在元素%d, 删除失败\n", val);
        }
        break;
    }
    case 'f':
    {
    
    
        if (!list_is_empty(head))
        {
    
    
            printf("链表中数据元素如下:\n");
            traverse(head);
        }
        else
        {
    
    
            printf("链表为空无法遍历!\n");
        }
        break;
    }
    }
    printf("\n\n\n\n\n\n\n\n\n\n\n\n");
    return;
}

//linkedlist.h

#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_
#include <stdbool.h>

typedef int elemtype; //本程序使用的数据元素是最简单的整型元素, 可随使用情况修改;

typedef struct node
{
    
    
    elemtype data;
    struct node *next;
} * linkedlist;
typedef struct node pnode;

//1) 构造一个链表头结点;
linkedlist init_list_head(void);
/*----------------------------------------------------------------------*/

//2) 销毁链表;
void destroy_list(linkedlist head);
/*----------------------------------------------------------------------*/

//3) 判断结点是否为尾结点;
bool node_is_last(linkedlist pos);
/*----------------------------------------------------------------------*/

//4) 判断链表是否为空;
bool list_is_empty(linkedlist head);
/*----------------------------------------------------------------------*/

//5) 获取链表数据元素个数;
int list_length(linkedlist head);
/*----------------------------------------------------------------------*/

//6) 查找链表中指定值的位置;
pnode *find(elemtype x, linkedlist head);
/*----------------------------------------------------------------------*/

//7) 查找链表中指定值的前驱结点位置;
pnode *find_previous(elemtype x, linkedlist head);
/*----------------------------------------------------------------------*/

//8) 在链表第pos个位置后插入新数据x;
void insert(linkedlist head, pnode *pos, elemtype x);
/*----------------------------------------------------------------------*/

//9) 删除链表中的数据元素x;
bool cancel(linkedlist head, elemtype x);
/*----------------------------------------------------------------------*/

//10) 遍历链表;
void traverse(linkedlist head);
/*----------------------------------------------------------------------*/

#endif

//linkedlist.c

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

linkedlist init_list_head(void)
{
    
    
    pnode *head = (pnode *)malloc(sizeof(pnode));
    if (NULL == head)
    {
    
    
        fprintf(stderr, "动态内存分配失败!本程序退出!\n");
        exit(EXIT_FAILURE);
    }
    head->next = NULL;
    return head;
}

void destroy_list(linkedlist head)
{
    
    
    pnode *temp = NULL;

    while (head != NULL)
    {
    
    
        temp = head;
        head = head->next;
        free(temp);
    }
    return;
}

bool node_is_last(linkedlist pos)
{
    
    
    return NULL == pos->next;
}

bool list_is_empty(linkedlist head)
{
    
    
    return NULL == head->next;
}

int list_length(linkedlist head)
{
    
    
    int len = 0;
    pnode *pos = head->next;

    while (pos != NULL)
    {
    
    
        ++len;
        pos = pos->next;
    }
    return len;
}

pnode *find(elemtype x, linkedlist head)
{
    
    
    pnode *pos = head->next;

    while (pos != NULL && pos->data != x)
    {
    
    
        pos = pos->next;
    }
    return pos;
}

pnode *find_previous(elemtype x, linkedlist head)
{
    
    
    pnode *pos = head;

    while (pos->next != NULL && pos->next->data != x)
    {
    
    
        pos = pos->next;
    }
    return pos;
}

void insert(linkedlist head, pnode *pos, elemtype x)
{
    
    
    pnode *new_node = (pnode *)malloc(sizeof(pnode));
    if (NULL == new_node)
    {
    
    
        fprintf(stderr, "动态内存分配失败!本程序退出!\n");
        exit(EXIT_FAILURE);
    }
    new_node->data = x;
    new_node->next = pos->next;
    pos->next = new_node;
    return;
}

bool cancel(linkedlist head, elemtype x)
{
    
    
    pnode *temp;
    pnode *pos = find_previous(x, head);

    if (!node_is_last(pos))
    {
    
    
        temp = pos->next;
        pos->next = temp->next;
        free(temp);
        return true;
    }
    return false;
}

void traverse(linkedlist head)
{
    
    
    pnode *pos = head->next;

    while (pos != NULL)
    {
    
    
        printf("%d ", pos->data);
        pos = pos->next;
    }
    return;
}

//----------------------------------------------------------------------------

//----------------------------2021年1月12日 -------------------------------

猜你喜欢

转载自blog.csdn.net/m0_46181359/article/details/112532001