#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; /* 雙向串列目前節點指標 */
/* 程式範例: createDList.c - 函數: 建立雙向串列 */
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; }
/* 程式範例: insertDNode.c - 函數: 插入節點 */
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; /* 插入節點指向新節點 */
}
}
}
/* 程式範例: deleteDNode.c - 函數: 刪除節點 */
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); /* 釋回刪除節點記憶體 */
}
/* 主程式 */
int main() {
char temp; /* 宣告變數 */
int data[6]={ 1, 2, 3, 4, 5, 6 }; /* 建立串列的陣列 */
createDList(6, data); /* 建立雙向串列 */
while ( temp != 'E' && temp != 'e' ) {
printDList(); /* 顯示雙向串列 */
printf("[F]往下移動 [B]往前移動 [A]新增節點 [D]刪除節點");
printf("[R]重設 [V]節點值 [E]離開 ==> ");
scanf("%s", &temp); /* 讀入選項 */
switch ( temp ) {
case 'F':
nextNode(); /* 往下移動 */
break;
case 'B':
previousNode(); /* 往前移動 */
break;
case 'A':
scanf("%d", &temp); /* 讀取新編號 */
insertDNode(readNode(), temp);
resetNode(); /* 重設目前指標 */
break;
case 'D':
deleteDNode(readNode());
resetNode(); /* 重設目前指標 */
break;
case 'R':
resetNode();
break;
case 'V':
printf("節點值: %d\n", readNode()->data);
break;
}
}
system("PAUSE");
return 0;
}
評分: ★★★★☆
回覆刪除Great !