2015-11-19 205 views
0

我的英文不是很好,但希望你們能理解我想說什麼。因此,這是鏈表的代碼,並且在運行程序並添加信息之後,它可以在printListStart()處打印。現在,我無法在printListEnd()上編寫代碼,並且我想從末尾顯示代碼(相反)。反向鏈接列表

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <conio.h> 


//function prototype 
void addToStart();  //add node to beginning of linked list 
void addToEnd();  //add node to end of linked list 
void removeNodeAt(); //remove node that matches element entered 
void printListStart();  //print nodes from start 
void printListEnd();  //print node from end 

void startlist(); //create NULL list 
void menu();  //selection 

//global variables 
int option, number; 
char name[20], gender[10],address[50],description[50]; 


//declare structure for node 
struct node 
{ 
    char customer_name[20]; 
    int customer_number; 
    char gender_[10]; 
    char customer_address[50]; 
    char order_description[50]; 
    struct node *next; 

}*newnode, *list, *prev, *temp, *tmpdisplay; 

void main() 
{ 

    startlist(); //function call to create empty list 

    do 
    { 

     menu();  //function call to show menu 

     switch (option) 
     { 
     case 1: system("cls"); addToStart(); break; 
     case 2: system("cls"); addToEnd(); break; 
     case 3: system("cls"); removeNodeAt(); break; 
     case 4: system("cls"); printListStart(); break; 
     case 5: system("cls"); printListEnd(); break; 
     case 6: exit(0); 
     default: 
      printf("Invalid Option"); 
      getch(); 
     } 

    } while (option != 6); 


}//end main 


void startlist() 
{ 
    list = NULL;  //create empty list 
} 

void menu() 
{ 

    printf("***LINKED LIST***\n\n"); 
    printf(" 1. Add New Node At Start\n"); 
    printf(" 2. Add New Node At End\n"); 
    printf(" 3. Remove Node\n"); 
    printf(" 4. Print Linked List From Start\n"); 
    printf(" 5. Print Linked List From End\n"); 
    printf(" 6. Quit\n"); 

    printf("\nSelect a task: ");  //allow user to select choice 
    scanf("%d", &option); 
} 

void addToStart() 
{ 
    newnode = (struct node*) malloc(sizeof(struct node)); //allocates memory space for new node 

    printf("Enter the customer name:\n"); 
    scanf("%s", &name); 
    printf("Enter then customer number:\n"); 
    scanf("%d", &number); 
    printf("Enter the Oder Description:\n"); 
    scanf("%s", &description); 
    printf("Enter the Gender:\n"); 
    scanf("%s", &gender); 
    printf("Enter the Customer Address:\n"); 
    scanf("%s", &address); 

    newnode->customer_number = number; 
    strcpy(newnode->customer_name, name);  //using stringcopy to copy name to customer_name in node 
    strcpy(newnode->order_description, description);  //using stringcopy to copy transdes to transaction_description in node 
    strcpy(newnode->gender_, gender); 
    strcpy(newnode->customer_address, address); 
    newnode->next = NULL; //set node pointer to NULL 



    if (list == NULL) 
     list = newnode; //if list is empty, node is assigned to list 
    else 
    { 
     newnode->next = list; //if list not empty, newnode pointer equals to list first node 
     list = newnode;  //assign newnode to list, newnode is at the start of the list 
    } 
} 


void addToEnd() 
{ 
    newnode = (struct node*) malloc(sizeof(struct node)); //allocate new memory space for new node 

    printf("Enter the customer name:\n"); 
    scanf("%s", &name); 
    printf("Enter then customer number:\n"); 
    scanf("%d", &number); 
    printf("Enter the Oder Description:\n"); 
    scanf("%s", &description); 
    printf("Enter the Gender:\n"); 
    scanf("%s", &gender); 
    printf("Enter the Customer Address:\n"); 
    scanf("%s", &address); 

    newnode->customer_number = number; 
    strcpy(newnode->customer_name, name); 
    strcpy(newnode->order_description, description); 
    strcpy(newnode->gender_, gender); 
    strcpy(newnode->customer_address, address); 
    newnode->next = NULL; 

    if (list == NULL) 
     list = newnode; //if list is empty, assign newnode to list as first node 
    else 
    { 
     temp = list;  //list not empty, assign temp as list 
     while (temp->next != NULL) //while pointer does not point to NULL/empty 
     { 
      temp = temp->next;  //move to subsequent node 
     } 
     temp->next = newnode;  //loop exits when last node is reached, last node's pointer points to newnode 
    } 
} 

void removeNodeAt() 
{ 
    printf("Enter customer number to delete: \n"); 
    scanf("%d", &number); 

    if (list == NULL)  //check if list is empty 
     printf("\n\nLIST IS EMPTY\n\n"); 

    //if list not empty, match number to cust_no in first node 
    else if (number == list->customer_number) 
    { 

     list = list->next; //match found, first node is skipped (deleted) 
    } 
    else //match not found in first node, move to subsequent nodes 
    { 
     temp = list; //assign temp as list 
     while (temp->customer_number != number) 
     { 
      //if match not found 
      prev = temp;  //prev is pointing to linked list 
      temp = temp->next;//temp is pointing to next node 
     } 

     printf("Node deleted:"); 
     printf("\n%s\n", prev->customer_name); 
     printf("%d\n", prev->customer_number); 
     printf("%s\n\n", prev->gender_); 
     prev->next = prev->next->next; //match found, skip/jump the node (delete) 
    } 
} 

void printListStart() 
{ 
    if (list == NULL) 
     printf("\n\nLIST IS EMPTY\n\n"); 
    else 
    { 
     tmpdisplay = list; 
     while (tmpdisplay != NULL) 
     { 
      printf("\n%s\n", tmpdisplay->customer_name); 
      printf("%d\n", tmpdisplay->customer_number); 
      printf("%s\n", tmpdisplay->gender_); 
      printf("%s\n", tmpdisplay->order_description); 
      printf("%s\n", tmpdisplay->customer_address); 
      tmpdisplay = tmpdisplay->next; 
     } 
    } 
} 


void printListEnd() 
{ 

} 
+0

對不起............ – gaetanoM

回答

1

如果由於某種原因無法使用雙向鏈表,您的選擇是使用嵌套循環或使用遞歸。這兩種解決方案都很糟糕。這裏的嵌套循環的解決方案,這是可怕的,因爲它運行在O(N^2)時間:

void printListEnd() 
{ 
    struct node *end; 

    if (list == NULL) 
     printf("\n\nLIST IS EMPTY\n\n"); 
    else 
    { 
     end = NULL; 
     while (end != list) 
     { 
      tmpdisplay = list; 
      while (tmpdisplay->next != end) 
       tmpdisplay = tmpdisplay->next; 
      printf("\n%s\n", tmpdisplay->customer_name); 
      printf("%d\n", tmpdisplay->customer_number); 
      printf("%s\n", tmpdisplay->gender_); 
      printf("%s\n", tmpdisplay->order_description); 
      printf("%s\n", tmpdisplay->customer_address); 
      end = tmpdisplay; 
     } 
    } 
} 

這裏的遞歸解決方案,這是可怕的,因爲它正比於列表的長度浪費堆棧空間:

static void printListEndRecurse(struct node *list) 
{ 
    if (list->next) 
     printListEndRecurse(list->next); 
    tmpdisplay = list; 
    printf("\n%s\n", tmpdisplay->customer_name); 
    printf("%d\n", tmpdisplay->customer_number); 
    printf("%s\n", tmpdisplay->gender_); 
    printf("%s\n", tmpdisplay->order_description); 
    printf("%s\n", tmpdisplay->customer_address); 
} 

void printListEnd() 
{ 
    if (list == NULL) 
     printf("\n\nLIST IS EMPTY\n\n"); 
    else 
     printListEndRecurse(list); 
} 
2

最簡單的方法是創建一個雙向鏈表,其中每個節點具有下一個和以前的指針,其中next指向下一個節點(比如你現在正在做的),且先前指向前一個節點。您還需要指向列表的前端和末尾的指針。要反向打印它,從指向最後一個節點的指針開始,並按照前面的指針而不是下一個指針。

struct node 
{ 
    char customer_name[20]; 
    int customer_number; 
    char gender_[10]; 
    char customer_address[50]; 
    char order_description[50]; 
    struct node *next; 
    struct node *prev; 
}*newnode, *list, *prev, *temp, *tmpdisplay, *listend; 

當添加一個節點到最後,prev爲新節點listend,並設置listend到新節點。

1

對不起,但我立即想到了遞歸。爲什麼不給這個夢幻般的技術提供一個機會?讓我來試試:

void printListEnd(struct node *myList) 
    { 
     if (myList != NULL) { 
      printListEnd(myList->next); 
      printf("\n%s\n", myList->customer_name); 
      printf("%d\n", myList->customer_number); 
      printf("%s\n", myList->gender_); 
      printf("%s\n", myList->order_description); 
      printf("%s\n", myList->customer_address); 
     } 
    } 

要叫你需要通過你的變量列表(列表的根節點)的功能。

+0

如果可用的遞歸深度(堆棧)超過列表長度,這是一個很好的解決方案。根據你的系統,這種無限遞歸是不鼓勵的。 – chux

0

接受答案後

分配一個數組來存儲鏈接地址。然後以相反的順序打印數組元素。 O(n)時間。

// Find size 
    size_t n = 0; 
    struct node *p = myList; 
    while (p) { 
    p = p->next; 
    n++; 
    } 

    // Build array 
    struct node **list = malloc(sizeof *list * n); 
    if (list) { 
    struct node **walker = list; 
    p = myList; 
    while (p) { 
     *walker = p; 
     walker++; 
     p = p->next; 
    } 

    // Print list 
    while (walker != list) { 
     walker--; 
     print_list(*walker); 
    } 

    free(list); 
    list = NULL; 
    } 

此方法不使用功能遞歸。