1. 程式人生 > 其它 >資料結構線性表之單鏈表的基本操作及選單應用(C程式實現)

資料結構線性表之單鏈表的基本操作及選單應用(C程式實現)

技術標籤:資料結構與演算法分析(C/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日 -------------------------------