小笨笨的DS學習網誌

★------------- ★------ ★-------------------- ★-------------------- ★--------------------

2010年5月30日 星期日

作業13~修改Ch4-5-3.c為Ch4-5-3e.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; /* 雙向串列目前節點指標 */
/* 程式範例: 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' ) {

      printf("原來的串列: ");
      printDList(); /* 顯示雙向串列 */
      printf("[F]往下移動 [B]往前移動 [A]新增節點 [D]刪除節點");
      printf("[R]重設 [V]節點值 [E]離開 ==> ");
      scanf("%s", &temp); /* 讀入選項 */
      switch ( temp ) {
         case 'F':

         case 'f':
            nextNode(); /* 往下移動 */
            break;
         case 'B':

         case 'b':
            previousNode(); /* 往前移動 */
            break;
         case 'A': 

         case 'a':             printf("請輸入新號碼(7~100) ==> ");
            scanf("%d", &temp); /* 讀取新編號 */
            insertDNode(readNode(), temp);
            resetNode(); /* 重設目前指標 */
            break;
         case 'D':

         case 'd':
            deleteDNode(readNode());
            resetNode(); /* 重設目前指標 */
            break;
         case 'R':

         case 'r':
            resetNode();
            break;
         case 'V':

         case 'v':
            printf("節點值: %d\n", readNode()->data);
            break;
      }
   }
   system("PAUSE");
   return 0;
}

1 則留言: