2012-08-05 17 views
5

Sto cercando di ordinare un elenco collegato trovando il valore più grande, cancellandolo dalla sua posizione e quindi inserendolo nella parte superiore dell'elenco.Ordinamento di un elenco collegato in C

La difficoltà che sto incontrando è l'effettiva eliminazione e inserimento in alto. Il problema sembra essere nella condizione if del ciclo while contenuto nella funzione sortList, ma non sono sicuro di come risolverlo.

Qualsiasi aiuto sarebbe apprezzato.

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

typedef struct node{ 
    int num; 
    struct node *next; 
} Node, *NodePtr; 

void printList(NodePtr np); 
NodePtr makeList(void); 
NodePtr makeNode(int n); 
NodePtr sortList(NodePtr list); 

int main(void) { 
    NodePtr list; 
    printf("Enter numbers for the list (0 to end)\n"); 
    list = makeList(); 
    printList(list); 
    list = sortList(list); 
    printList(list); 
    return 0; 
} 

NodePtr makeList(void) { 
    NodePtr makeNode(int), np, top, last; 
    int n; 
    top = NULL; 
    if(scanf("%d", &n) != 1)n = 0; 
    while(n != 0) { 
     np = makeNode(n); 
     if(top == NULL)top = np; 
     else last->next = np; 
     last = np; 
     if(scanf("%d", &n)!=1)n=0; 
    } 
    return top; 
} 


void printList(NodePtr np) { 
    while(np != NULL) { 
     printf("%d\n", np->num); 
     np = np->next; 
    } 
} 

NodePtr makeNode(int n) { 
    NodePtr np = (NodePtr)malloc(sizeof(Node)); 
    np->num = n; 
    np->next = NULL; 
    return np; 
} 

NodePtr sortList(NodePtr list) { 
    NodePtr top = list; 
    NodePtr curr = NULL; 
    NodePtr largest; 
    NodePtr prev; 
    prev = NULL; 
    curr = top; 
    largest = top; 

    while(curr != NULL) { 
     prev = curr; 
     if(curr->num > largest->num) { 
      largest = curr; 
      prev->next = curr->next; 
      largest->next = top; 
     } 
     curr = curr->next; 
    } 
    if(prev == NULL) { 
     largest->next = top; 
     return largest; 
    } 
    return largest; 
} 
+2

Ci sono una serie di domande circa l'ordinamento liste collegate in C; molti di loro sono elencati come domande correlate sul RHS della pagina.Hai guardato qualcuno di loro per vedere se sono rilevanti per il tuo problema? –

risposta

0

This dovrebbe davvero aiutarti. È un post molto bello

+0

Le risposte su Stack Overflow dovrebbero generalmente stare da sole (anche se le citazioni sono ottime). Se desideri condividere un link, puoi farlo in un commento. –

+0

Lezione appresa. Andrà bene. – Prasanth

0

Scrivendo a largest->next hai sovrascritto curr->next. Quindi finisci per ricominciare tutto da capo.

Assicurarsi che:

  1. lista rimane coerente
  2. vostra lista iteratore rimane coerente

Ma nel complesso, il codice sembra essere pesantemente rotto, credo che ci potrebbe essere una coppia altri errori nella tua logica di ordinamento.

0

I seguenti sono alcuni dei problemi che esistono nella vostra logica di ordinamento:

  1. si imposta il puntatore prev al curr all'inizio del ciclo stesso, che non è corretto. In questo modo, si sta rendendo il puntatore corrente e il puntatore del nodo precedente lo stesso che rende impossibile eliminare il nodo.
  2. Si consiglia di assegnare il puntatore più grande anche in alto per cui facilita la possibilità di impostare il più grande-> accanto al nodo superiore reale.

il codice può modificato come qui di seguito (solo un puntatore, è necessario verificare la presenza di altri problemi da soli):

while(curr != NULL) 
{ 

    if(curr->num > largest->num) 
    { 
     largest = curr; 
     prev->next = curr->next; 
     largest->next = top; 
     top = largest; 

    } 
    prev = curr; 
    curr = curr->next; 
} 
+0

c'è ancora un problema con il puntatore, curr sarà sempre in alto: più grande punta allo stesso nodo di curr. metti il ​​più grande-> più in alto poi curr-> i prossimi punti in alto. quando scrivi curr = curr-> next, in realtà metti top in curr (perché hai scritto in alto in maggiore (maggiore = curr in questo punto)). in modo da retart infinitamente dall'alto. –

1

C'è problemi nella funzione sortList.

Questa funzione inserisce solo alcuni nodi di grandi dimensioni all'inizio della lista. Non sta citando tutta la lista. è possibile un algoritmo di ordinamento per ordinare il file: quicksort/bubblesort/... ho messo un codice facendo un ordinamento alla fine di questa risposta.

qui è un codice che fa l'ordinamento della lista:

// che sostituisce grande nodo con prima poi fare la stessa operazione con sottolista (elemento lista-prima)

NodePtr sortList(NodePtr list) 
{ 

// 
if(list == null || list->next == null) 
    return list; // the list is sorted. 

//replace largest node with the first : 

//1- find largest node : 
NodePtr curr, largest,largestPrev; 
curr = list; 
largest = list; 
prev = list; 
largestPrev = list; 
while(curr != NULL) { 
     if(curr->num > largest->num) { 
      largestPrev = prev; 
      largest = curr; 
     } 
     prev = curr; 
     curr = curr->next; 

    } 
//largest node is in largest. 

//2- switching firt node and largest node : 
NodePtr tmp; 
if(largest != list) 
{ 
    largestPrev->next = list; 
    tmp = list->next; 
    list->next = largest->next; 
    largest->next = tmp; 
} 

// now largest is the first node of the list. 

// calling the function again with the sub list : 
//   list minus its first node : 
largest->next = sortList(largest->next); 


return largest; 
} 
+1

Correggi il tuo codice (prev sempre punta alla coda nella tua risposta), devi aggiungere un nuovo puntatore largest_prev e lo imposti a prev in caso di: if (curr-> num> largest-> num), quindi usalo invece di prev (largest_prev-> next = list) – TOC

+0

@TOC: ty, done. codice più accessibile potrebbe essere quello di utilizzare una funzione che cerca l'elemento più grande e una funzione che cambia nodo. –

+0

Questo algoritmo non funziona quando si ha una lista come questa: 524361 – user1511417

1

qui è il mio tentativo di ordinare una lista collegata singolarmente usando l'algoritmo QuickSort. Se si conosce n, il tempo di esecuzione sarà O (n log n). Controlla se questo aiuta.

#include "malloc.h" 

typedef struct node { 
    struct node *next; 
    int val; 
} node; 

bool insert_node(struct node **head, int val) 
{ 
    struct node *elem; 
    elem = (struct node *)malloc(sizeof(struct node)); 
    if (!elem) 
     return false; 
    elem->val = val; 
    elem->next = *head; 
    *head = elem; 
    return true; 
} 

int get_lval(struct node *head, int l) 
{ 
    while(head && l) { 
     head = head->next; 
     l--; 
    } 
    if (head != NULL) 
     return head->val; 
    else 
     return -1; 
} 

void swap(struct node *head, int i, int j) 
{ 
    struct node *tmp = head; 
    int tmpival; 
    int tmpjval; 
    int ti = i; 
    while(tmp && i) { 
     i--; 
     tmp = tmp->next; 
    } 
    tmpival = tmp->val; 
    tmp = head; 
    while(tmp && j) { 
     j--; 
     tmp = tmp->next; 
    } 
    tmpjval = tmp->val; 
    tmp->val = tmpival; 
    tmp = head; 
    i = ti; 
    while(tmp && i) { 
     i--; 
     tmp = tmp->next; 
    } 
    tmp->val = tmpjval; 
} 


struct node *Quick_Sort_List(struct node *head, int l, int r) 
{ 
    int i, j; 
    int jval; 
    int pivot; 
    i = l + 1; 
    if (l + 1 < r) { 
     pivot = get_lval(head, l); 
     printf("Pivot = %d\n", pivot); 
     for (j = l + 1; j <= r; j++) { 
      jval = get_lval(head, j); 
      if (jval < pivot && jval != -1) { 
       swap(head, i, j); 
       i++; 
      } 
     } 
     swap(head, i - 1, l); 
     Quick_Sort_List(head, l, i); 
     Quick_Sort_List(head, i, r); 
    } 
    return head; 
} 

struct node *Sort_linkedlist(struct node *head) 
{ 
    struct node *tmp = head; 
    // Using Quick sort. 
    int n = 0; 

    while (tmp) { 
     n++; 
     tmp = tmp->next; 
    } 
    printf("n = %d\n", n); 
    head = Quick_Sort_List(head, 0, n); 
    return head; 
} 

void print_list(struct node *head) 
{ 
    while(head) { 
     printf("%d->", head->val); 
     head = head->next; 
    } 
    printf("\n"); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    struct node *head = NULL; 
    struct node *shead = NULL; 

    insert_node(&head, 10); 
    insert_node(&head, 12); 
    insert_node(&head, 9); 
    insert_node(&head, 11); 
    insert_node(&head, 7); 
    insert_node(&head, 1); 
    insert_node(&head, 3); 
    insert_node(&head, 8); 
    insert_node(&head, 5); 
    insert_node(&head, 2); 
    insert_node(&head, 4); 
    insert_node(&head, 6); 
    print_list(head); 

    shead = Sort_linkedlist(head); 
    print_list(shead); 

    return 0; 
} 
0
// Program to sort a single linked list in ascending order 
// (without exchanging data in the nodes) 
/************************************************************************** 

There are two methods of sorting presented here(At a time,we can use any of 
these two functions to sort our single linked list.) - 

1. Function 'void Sort()' - This function uses selection sort method(I 
          think). 
    In this function,a node whose data is the smallest in the list is made 
    as 'head' node(i.e. starting node of the list) by scanning the whole list 
    once.Then from the remaining list,again a node with the smallest data is 
    found out whose address is kept in the 'next' field of previous node(head 
    node).This process continues to sort the whole list. 
2. Function 'void Sort_method2()' - This function uses insertion sort 
            method(I think). 
    In this function,starting from second node in the list, all previous node 
    data(starting from 'head' node) are compared with current reference node 
    (which is initially second node in the list).If 'data' field of current 
    reference node is smaller than that of any of its previous nodes,then 
    suitable changes in the 'next' field of corresponding nodes are made.If 
    data in the current reference node is smaller than that in the 'head' node, 
    then the current reference node is made as 'head' node. 

    *********************************************************************/ 

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

struct node 
{ 
int data; 
struct node *next; 
}; 

struct node *head,*head1; 

void Create_node(int data); 
void display(); 
void Sort(); 
void Sort_method2(); 


void main() 
{ 
int choice,d; 
clrscr(); 
while(1) 
{ 
    printf("\n 1.Create new node"); 
    printf("\n 2.Sort in ascending order"); 
    printf("\n 3.Exit"); 
    printf("\nEnter your choice : "); 
    scanf("%d",&choice); 

    switch(choice) 
    { 
    case 1: printf("\nEnter data :"); 
      scanf("%d",&d); 
      Create_node(d); 
      break; 
    case 2: Sort();  // At a time,we can use any of these two 
      //Sort_method2(); // functions to sort our single linked list. 
      break; 
    case 3: exit(0); 
    default:exit(0); 
    } 
    } // end of while(1) 
} // end of main() 

//-------------------------------------------- 
void Create_node(int d) 
{ 
    struct node *newnode,*temp; 
    newnode = (struct node *)malloc(sizeof(struct node)); 
    newnode -> data = d; 
    newnode -> next = NULL; 
    if(head == NULL) 
    head = newnode; 
    else 
    { 
     temp = head; 
     while(temp -> next != NULL) 
     temp = temp -> next; 

     temp -> next = newnode; 
    } // end of 'else' 
} // end of 'Create_node(int d)' 

//--------------------------------------------- 
void display() // Print linked list contents 
{ 
    struct node *temp; 
    printf("\nList contents are :\n"); 
    temp = head; 
    while(temp != NULL) 
    { 
    printf(" Data = %d Address = %u\n",temp->data,temp); 
    temp = temp->next; 
    } 
    printf("\n"); 
} 
//-------------------------------------------- 
void Sort() 
{ 
    struct node *t,*t1,*t2,*t3; 
    t1 = head; 
    head1 = head; 
    if(head == NULL) 
    printf("\nThe linked list is empty!"); 
    else 
    { 
    while((t2 = t1 -> next) != NULL) 
    { 
     while(t2 != NULL) 
     { 
     t3 = t2 -> next; 
     if(t1 -> data > t2 -> data) 
     { 
      t2 -> next = t1; 
      for(t = t1; t -> next != t2;t = t -> next); 

      t -> next = t3; 
      t1 = t2;  // t1 = Node with smaller data 
      t2 = t3;  // t2 = Node to be compared with t1 
     } // end of 'if' 
     else 
     { 
      // t1 = t1;  // That is,no change in t1. 
      t2 = t3; 
     } 
     } // end of ' while(t2 != NULL)' 

     if(head == head1) // We want this action only for first pass of 
     {     // outer while() loop.Only initially, head = head1. 
     head = t1; 
     head1 = t1 -> next; 
     } // end of 'if(head == head1)' 
     else 
     { 
     for(t = head;t -> next != head1; t = t -> next); 

     t -> next = t1; 
     head1 = t1 -> next; 
     } // end of 'else' 

     t1 = t1 -> next; 
    } // end of 'while((t2 = t1 -> next) != NULL)' 

    display(); // Display the list. 
    } // end of 'else' of 'if(head == NULL)' 
} // end of 'Sort()' 

//-------------------------------------------- 
void Sort_method2() 
{ 
struct node *t,*t1,*t2,*tt; 
if(head == NULL) 
    printf("\nThe linked list is empty!"); 
else 
{ 
    t1 = head -> next; 
    while(t1 != NULL)       // This is i-loop(outer loop). 
    { 
    t2 = t1 -> next; 
    for(t = head; t != t1; t = t -> next) // This is j-loop(inner loop). 
    { 
     if(t1->data < t->data) 
     { 
     t1 -> next = t; 
     for(tt=head; tt->next != t1; tt=tt->next); //end of for loop in 'if' 

     tt -> next = t2; 
     if(t == head) 
      head = t1; // There is only one statement in this 'if'. 
     else // i.e.,'if(t != head)' 
     { 
      for(tt=head; tt->next != t; tt=tt->next); 

      tt -> next = t1; 
     } 
     break; 
     } // end of 'if' 
    } // end of outer 'for' loop 
    t1 = t2; 
    }  // end of 'while' 

    display(); // Display the list. 
}  // end of 'else' of 'if(head == NULL)' 
}   // end of 'Sort_method2()' 
Problemi correlati