/* 程式範例: Ch4-5-3.c */
#include <stdio.h>
#include <stdlib.h>
struct Node { /* Node節點結構 */
int data; /* 結構變數宣告 */
struct Node *next; /* 指向下一個節點 */
struct Node *previous; /* 指向前一個節點 */
};
typedef struct Node DNode; /* 雙向串列節點的新型態 */
typedef DNode *DList; /* 雙向串列的新型態 */
DList first = NULL; /* 雙向串列的開頭指標 */
DList now = NULL; /* 雙向串列目前節點指標 */
/* 抽象資料型態的操作函數宣告 */
void creatDList(int len, int *array);
void printDList();
void nextNode();
void previousNode();
void resetNode();
DList readNode();
void insertDNode(DList ptr, int d);
void deleteDNode(DList ptr);
void createDList(int len, int *array) {
int i;
DList newnode, before; /* 配置第1個節點 */
first = (DList) malloc(sizeof(DNode));
first->data = array[0]; /* 建立節點內容 */
first->previous = NULL; /* 前節點指標為NULL */
before = first; /* 指向第一個節點 */
now = first; /* 重設目前節點指標 */
for ( i = 1; i < len; i++ ) {
/* 配置節點記憶體 */
newnode = (DList) malloc(sizeof(DNode));
newnode->data = array[i]; /* 建立節點內容 */
newnode->next = NULL; /* 下節點指標為NULL */
newnode->previous=before; /* 將新節點指向前節點 */
before->next=newnode; /* 將前節點指向新節點 */
before = newnode; /* 新節點成為前節點 */
}
}
/* 函數: 顯示雙向串列的節點資料 */
void printDList() {
DList current = first; /* 目前的節點指標 */
while ( current != NULL ) { /* 顯示主迴圈 */
if ( current == now )
printf("#%d#", current->data);
else
printf("[%d]", current->data);
current = current->next; /* 下一個節點 */
}
printf("\n");
}
/* 函數: 移動節點指標到下一個節點 */
void nextNode() {
if ( now->next != NULL )
now = now->next; /* 下一個節點 */
}
/* 函數: 移動節點指標到上一個節點 */
void previousNode() {
if ( now->previous != NULL )
now = now->previous; /* 前一個節點 */
}
/* 函數: 重設節點指標 */
void resetNode() { now = first; }
/* 函數: 取得節點指標 */
DList readNode() { return now; }
/* 函數: 刪除節點 */
void deleteDNode(DList ptr) {
if ( ptr->previous == NULL ) { /* 是否有前一個節點 */
/* 情況1: 刪除第一個節點 */
first = first->next; /* 指向下一個節點 */
first->previous = NULL; /* 設定指向前節點指標 */
}
else {
if ( ptr->next == NULL ) { /* 是否有下一個節點 */
/* 情況2: 刪除最後一個節點 */
ptr->previous->next = NULL; /* 前節點指向NULL */
}
else {
/* 情況3: 刪除中間的節點 */
/* 前節點指向下一節點 */
ptr->previous->next = ptr->next;
/* 下一節點指向前節點 */
ptr->next->previous = ptr->previous;
}
}
free(ptr); /* 釋回刪除節點記憶體 */
}
void insertDNode(DList ptr, int d) {
/* 配置節點記憶體 */
DList newnode = (DList) malloc(sizeof(DNode));
newnode->data = d; /* 建立節點內容 */
if ( first == NULL ) /* 如果串列是空的 */
first = newnode; /* 傳回新節點指標 */
if ( ptr == NULL ) {
/* 情況1: 插在第一個節點之前, 成為串列開始 */
newnode->previous = NULL; /* 前指標為NULL */
newnode->next = first; /* 新節點指向串列開始 */
first->previous = newnode; /* 原節點指向新節點 */
first = newnode; /* 新節點成為串列開始 */
}
else {
if ( ptr->next == NULL ) { /* 是否是最後一個節點 */
/* 情況2: 插在串列的最後 */
ptr->next = newnode; /* 最後節點指向新節點 */
newnode->previous=ptr; /* 新節點指回最後節點 */
newnode->next = NULL; /* 後回指標為NULL */
}
else {
/* 情況3: 插入節點至串列的中間節點 */
ptr->next->previous = newnode; /* 指回新節點 */
newnode->next = ptr->next; /* 指向下一節點 */
newnode->previous=ptr; /* 新節點指回插入節點 */
ptr->next = newnode; /* 插入節點指向新節點 */
}
}
}
/* 主程式 */
int main() {
char temp = 1; /* 宣告變數 */
int num=0;
int data[6]={ 1, 2, 3, 4, 5, 6 }; /* 建立串列的陣列 */
createDList(6, data); /* 建立雙向串列 */
while ( temp != 'e' && temp != 'E' ) {
printf("原來的串列: ");
printDList(); /* 顯示串列 */
printf("[F]往下移動 [B]往前移動 [A]新增節點 \n");
printf("[D]刪除節點 [R]重設 [V]節點值 [E]離開 ==> ");
temp=getch(); /* 讀入選項 */
printf("%c",temp);
switch ( temp ) {
case 'f':
case 'F': nextNode(); /* 往下移動 */
break;
case 'b':
case 'B': previousNode(); /* 往前移動 */
break;
case 'a':
case 'A':
printf("\n請輸入新號碼 ==> ");
scanf("%d", &num); /* 讀取新編號 */
insertDNode(readNode(), num);
resetNode();
break;
case 'd':
case 'D':
deleteDNode(readNode());
resetNode(); /* 重設目前指標 */
break;
case 'r':
case 'R':
resetNode();
break;
case 'v':
case 'V':
printf("\n============");
printf("\n節點值: %d\n",readNode()->data);
printf("============\n");
break;
case 'e':
case 'E': /* 刪除節點 */
break;
default:
printf("\n\n不明操作!!");
}
printf("\n\n");
}
system("PAUSE");
return 0;
}
getch(); will not show what the user keyin.
回覆刪除Suggest that you can printf the value of getch() to show what the user keyin.
評分: ★★★★☆
Excellent !
changed already!
回覆刪除