2010年5月30日 星期日

作業十三:雙向鏈結整合

/* 程式範例: 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;
}

2 則留言:

  1. getch(); will not show what the user keyin.
    Suggest that you can printf the value of getch() to show what the user keyin.

    評分: ★★★★☆
    Excellent !

    回覆刪除