連結串列操作源程式 (轉)
連結串列,是資料結構的基礎。利用連結串列,我們可以很好的實現資料的管理。但是我們經常在網上看見各式各樣的有關連結串列的問題,在此我給出了一個比較簡單但是功能比較強大的來給大家顯示關於連結串列的。如果你很深入的瞭解了下面程式的工作原理,說明你對連結串列的理解就算過關了,如果不能,請仔細閱讀一下下面的程式,特別注意程式指標的修改順序。 特別是連結串列的倒置程式,不超過10行就搞定了,還沒有額外的申請空間,何樂而不為? 程式在VC6下編譯透過
#include
#include
#include
#include
/* 書中的常量定義 */
#define OK 1
#define ERROR 0
#define OVERFLOW (-1)
typedef int Status;
/* 定義了一個學生的結構體 */
typedef struct {
int sn; /* 學號 */
char name[32]; /* 姓名 */
int re; /* 成績 */
} data_t;
/* 定義了連結串列的節點形式為一個單連結串列 */
typedef struct LNODE {
data_t data;
struct LNODE * next;
}node_t, *link_t;
/* 建立一個有頭節點的連結串列 */
link_t create_link();
/* 銷燬連結串列,釋放節點空間 */
void destroy_link(link_t head);
/* 在連結串列的第 idx 位置插入一個節點,節點的值由 d 給出*/
/* 注意 idx 為插入節點後的位置,且從0開始計算 */
Status insert_node(link_t head, int idx, data_t e);
/* 刪除連結串列的第 idx 個節點,並將刪除的內容填入e所指向的空間*/
/* idx也是從0開始計算 */
Status delete_node(link_t head, int idx, data_t* e);
/* 判斷連結串列是否為空 */
Status empty_link(link_t head);
/* 獲得連結串列的長度 */
int length_link(link_t head);
/* 獲得連結串列的第i個元素的位置,並返回該元素的指標,NULL表示無效 */
node_t* locate_link(link_t head, int idx);
/* 列印連結串列的內容 */
void print_link(link_t head);
/* 將一個連結串列倒置 */
void reverse_link(link_t head);
/* 鍵盤命令對映表 */
const char *help[] =
{
"?,h,H -- this helpn",
"a,A,i,I -- add a node, ex: a 10n",
"d,D -- del a node, ex: d 10n",
"p,P -- print this linkn",
"g,G -- get link numn",
"r,R -- reverse the linkn",
"x,X,q,Q -- exit this programn",
};
/* 程式入口 */
int main(int argc, char* argv[])
{
char cmd;
int i, idx;
data_t tmp;
link_t head = create_link();
for (i=0; i<10; i++) { /*預先插入10個節點*/
tmp.sn = i; tmp.score = 100-i; strcpy(tmp.name, "ttttt");
insert_node(head, i, tmp);
}
print_link(head);
printf("input command: ");
while ( cmd = getch())
{
printf("%cn", cmd);
switch (cmd)
{
case '?': case 'h': case 'H': /*列印幫助資訊*/
for (i=0; i<sizeof(help)/sizeof(help[0]); i++)
printf("t%s", help[i]);
printf("n");
break;
case 'a': case 'A': case 'i': case 'I': /*插入一個節點*/
printf("please input where do you want to insert: ");
scanf("%d", &idx);
if (idx < 0 || idx > length_link(head)) {
printf("insert perror!n");
break;
}
printf("please input the SN, name and score:");
scanf("%d%s%d", &tmp.sn, tmp.name, &tmp.score);
if (insert_node(head, idx, tmp) == ERROR){
printf("insert error!n");
break;
}
printf("insert OK!n");
print_link(head);
break;
case 'd': case 'D': /*刪除一個節點*/
printf("please input which do you want to delete: ");
scanf("%d", &idx);
if (idx < 0 || idx >= length_link(head)) {
printf("delete pos error!n");
break;
}
if (delete_node(head, idx, &tmp) == NULL) {
printf("input error!n");
break;
}
printf("delete OKn");
print_link(head);
break;
case 'p': case 'P': /* 列印連結串列*/
print_link(head);
break;
case 'x': case 'X': case 'q': case 'Q':/*退出程式*/
destroy_link(head);
return 0;
case 'r': case 'R': /*倒置連結串列*/
reverse_link(head);
printf("this link have been reversed!n");
print_link(head);
break;
default:
printf("input error!, for help, please input ?n");
}
printf("nninput command: ");
}
return 0;
}
link_t create_link()
{
link_t head;
head = (link_t)malloc(sizeof(node_t));
head->next = NULL;
head->data.sn = 0;
return head;
}
void destroy_link(link_t head)
{
node_t *p = head;
while (head != NULL) {
p = head->next;
free (head);
head = p;
}
}
void print_link(link_t head)
{
node_t *p = head->next; /*跳過頭節點*/
int cnt = 0;
printf("pos : SN %20s scoren", "name ");
while (p != NULL) {
printf("%04d: %4d%20s%4dn",
cnt++, p->data.sn, p->data.name, p->data.score);
p = p->next;
}
}
Status empty_link(link_t head)
{
if (head==NULL || head->next == NULL)
return OK;
else
return ERROR;
}
int length_link(link_t head)
{
int len = 0;
node_t *p = head->next;
for(; p!=NULL; p = p->next)
len++;
return len;
}
node_t* locate_link(link_t head, int idx)
{
int pos = -1;
node_t *p = head;
while (p!=NULL && pos < idx) {
p = p->next; pos ++;
}
return p;
}
Status insert_node(link_t head, int idx, data_t e)
{
node_t *add = NULL; /* 待加入的節點指標 */
node_t *p = locate_link(head, idx-1); /*注意查詢idx-1*/
if (p == NULL) return ERROR;
add = (node_t *)malloc(sizeof(node_t));
add->data = e;
add->next = p->next;
p->next = add;
return OK;
}
Status delete_node(link_t head, int idx, data_t *e)
{
node_t *p = locate_link(head, idx-1); /*注意查詢idx-1*/
node_t *q = NULL; /* p為待刪除的節點指標 */
if (p == NULL || p->next== NULL) return ERROR;
q = p->next;
*e = q->data;
p->next = q->next;
free (q);
return OK;
}
void reverse_link(link_t head)
{
node_t *p1, *p2;
p1 = head->next;
head->next = NULL;
while (p1 != NULL) {
p2 = p1->next;
p1->next = head->next;
head->next = p1;
p1 = p2;
}
}
大家看見了,上面的每一個子都很簡單,不超過10行。唯一的只有main函式比較長。而main函式卻實現了一個常用的選單操作的示例,包括幫助、連結串列的插入、刪除等功能的命令與功能實現的對應,也是各個函式功能組合為各種具體功能的實現。
——小兒科,大家別扔磚頭,雞蛋可以!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992971/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 連結串列操作
- 連結串列面試題(二)---連結串列逆序(連結串列反轉)面試題
- 反轉連結串列
- 旋轉連結串列
- 資料結構之連結串列篇(單連結串列的常見操作)資料結構
- 資料結構之連結串列操作資料結構
- #反轉連結串列_C++版 #反轉連結串列_Java版 @FDDLCC++Java
- 反轉連結串列、合併連結串列、樹的子結構
- 【LeetCode-連結串列】面試題-反轉連結串列LeetCode面試題
- 單連結串列簡單操作一
- 02-單連結串列的操作
- 程式碼隨想錄第3天 | 連結串列 203.移除連結串列元素,707.設計連結串列,206.反轉連結串列
- 帶頭結點的連結串列操作題
- 連結串列-雙向連結串列
- 連結串列-迴圈連結串列
- 資料結構之連結串列:206. 反轉連結串列資料結構
- 61. 旋轉連結串列
- 演算法 - 連結串列操作思想 && case演算法
- golang二級指標操作連結串列Golang指標
- 【程式碼隨想錄】二、連結串列:2、設計連結串列
- 【程式碼隨想錄】二、連結串列:1、移除連結串列元素
- 連結串列4: 迴圈連結串列
- 連結串列-單連結串列實現
- **203.移除連結串列元素****707.設計連結串列****206.反轉連結串列**
- 一文講透連結串列操作,看完你也能輕鬆寫出正確的連結串列程式碼
- 連結串列入門與插入連結串列
- (連結串列)連結串列的排序問題排序
- 圖解帶頭節點的單連結串列的反轉操作圖解
- java實現連結串列反轉Java
- leetcode 反轉連結串列LeetCode
- TypeScript 實現連結串列反轉TypeScript
- 翻轉連結串列常用寫法
- 1025 反轉連結串列
- 雙向連結串列的建立及基本操作
- VC++基礎 連結串列的操作示例C++
- 資料結構之連結串列與陣列(3):單向連結串列上的簡單操作資料結構陣列
- C++資料結構連結串列的基本操作C++資料結構
- 連結串列