資料結構線性表之單鏈表的基本操作及選單應用(C程式實現)
阿新 • • 發佈:2021-01-13
技術標籤:資料結構與演算法分析(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日 -------------------------------