簡體   English   中英

單鏈接列表上的快速排序

[英]Quicksort on Single Linked list

我試圖在單個鏈表上為QUICKSORT寫一個簡單的C代碼。 程序將獲得一個txt文件,其中包含密碼和該密碼的使用頻率。 程序應按順序對密碼進行排序。 有人可以告訴我如何編寫void qsort_list函數,因為我不了解如何獲取“ partiition()”所需的3個參數。

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


typedef struct list_element{
char passwort[100];
int haufigkeit;
struct list_element *next;
} list_element;

typedef struct list{ list;


void init_list(list* mylist)
{
mylist->first=NULL;
mylist->last=NULL;
}


void insert_front(list_element* le, list* mylist)
{
// HIER Code einfügen

if(mylist->first == NULL){
le->next = mylist-> first;
mylist->first=le;
mylist->last=le;
}
else {
le->next = mylist-> first;
mylist->first= le;
}
}

// Speicher für Listenelemente wieder freigeben
void free_list(list* mylist)
{
// HIER Code einfügen
}


// Namen, Zahlen Paare in Liste einlesen
void read_data(char* filename, list* mylist)
{
assert(mylist != NULL);
FILE* f=fopen(filename,"rb");
assert(f != NULL);
while (1)
{

list_element* temp = malloc(siezof(list_element))// * Speicher allozieren
fscanf(f,"%s %d",temp->passwort, &temp-> haufigkeit)// * Daten in list_element einlesen
insert_front(temp, mylist) // * insert_front benutzen um list_element in Liste einzufügen

}
fclose(f);
}

// Pivot finden, das die Liste aufteilt
list_element* partition( list* input, list* left, list* right )
{
list_element* pivot= list->last;
input= mylist;
while(mylist->first != mylist->last)
{
// HIER Code einfügen
list_element* list_right = list* right;
list_element* list_left = list* left;
list_element *i;
for(i=list->first; i != NULL; i=i->next){
if ((i -> haufigkeit) < (pivot -> haufigkeit)){
insert_front(i, list_left);
}
else{
insert_front(i,list_right);
}
}
}

}
return pivot;
}

/*
void partition1(){
    list* pivot= list->last;
}return pivot;
}
*/

void qsort_list(list* mylist)
{
list left = mylist;
list first;  //  = list mylist->first:
list pivot= list* last; 

partition(list* left, list* first, list* pivot);
pivot = 


}

// Liste ausgeben
void print_list(list* mylist)
{
// HIER Code einfügen:

}

// Argumente einlesen, Liste kreieren, verarbeiten und ausgeben
int main(int argc, char** args)
{
if (argc != 2)
{
printf("Nutzung: %s <Dateiname>\n",args[0]);
return 1;
}
list mylist;
init_list(&mylist);
read_data(args[1],&mylist);
qsort_list(&mylist);
printf("Sortierte Liste:\n");
print_list(&mylist);
free_list(&mylist);
return 0;
}

鏈表上的快速排序算法的總體思路是:

1-要選擇樞軸鍵,您需要在列表中選擇最后一個鍵。

2-將元素列表拆分為2個子列表:一個包含元素<樞軸(或<=),另一個包含元素> =樞軸(或>)。 您正在左右調用此列表。

3-訂購左右列表。 這是遞歸部分:您使用quicksort對每個子列表進行排序,除非列表為空或包含一個元素。

4-連接左右列表的元素。

因此,您的qsort_list必須類似於:

void qsort_list(list* mylist) {
    list left,right;
    int pivotKey= mylist->last->haufigkeit;
    /* stop condition: mylist empty or with 1 element*/
    if( (mylist->first == 0) || (mylist->first == mylist->last) )
        return;
    init_list(left);
    init_list(right);
    partition(mylist, &left, &right, pivotKey);
    /* recursive part: */
    qsort_list(&left);
    qsort_list(&right);
    join(mylist, &left, &right);
}

筆記:

  • 我將ivot更改為pivotKey,您只需要知道用於拆分列表的鍵即可。 它甚至可能是不存在的密鑰(例如,第一個密鑰和最后一個密鑰之間的平均值)
  • 基於上述內容,您必須創建分區函數,記住要從中獲取原始列表並將其插入一個子列表中,以更新原始列表。 分區后,您的原始列表將為空。 另外,您可以考慮只刪除較大的元素,這樣您的原始列表將替換左側的列表。
  • 您必須實現join函數,該函數將mylist中的left和right的所有元素(按此順序)插入。 您不需要一個個地移動元素,只需操縱第一個和最后一個指針即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM