简体   繁体   English

单链接列表上的快速排序

[英]Quicksort on Single Linked list

I'm trying to write a simply C code for QUICKSORT on single linked list. 我试图在单个链表上为QUICKSORT写一个简单的C代码。 Program will get a txt file with password and frequency of usage this password. 程序将获得一个txt文件,其中包含密码和该密码的使用频率。 Program should sort the passwords in order. 程序应按顺序对密码进行排序。 Can some one tell me how to write function void qsort_list because I don't understand how to get 3 parameters that "partiition()" need. 有人可以告诉我如何编写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;
}

The general idea of the quicksort algorithm over a linked list is: 链表上的快速排序算法的总体思路是:

1 - To choice a pivot key, in your case you are choosing the last key in the list. 1-要选择枢轴键,您需要在列表中选择最后一个键。

2 - To split the list of elements in 2 sublist: one with elements < pivot (or <=) and the other with elements >= pivot (or >). 2-将元素列表拆分为2个子列表:一个包含元素<枢轴(或<=),另一个包含元素> =枢轴(或>)。 You are calling this list left and right. 您正在左右调用此列表。

3 - To order the left and right lists. 3-订购左右列表。 This is the recursive part: you use quicksort to order each sublist, unless the list is empty or with one element. 这是递归部分:您使用quicksort对每个子列表进行排序,除非列表为空或包含一个元素。

4 - To concatenate the elements of left and right lists. 4-连接左右列表的元素。

So your qsort_list must be something like: 因此,您的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);
}

Notes: 笔记:

  • I changed pivot to pivotKey, you just need to know the key to split the list. 我将ivot更改为pivotKey,您只需要知道用于拆分列表的键即可。 It may even be a non-existing key (eg. the average between the first one and the last one) 它甚至可能是不存在的密钥(例如,第一个密钥和最后一个密钥之间的平均值)
  • Based on the said, you must create your partition function, remember to update the original list as you take elements from it and insert them in one sublist. 基于上述内容,您必须创建分区函数,记住要从中获取原始列表并将其插入一个子列表中,以更新原始列表。 Your original list will be empty after the partition. 分区后,您的原始列表将为空。 Alternatively, you can think on a way to just remove the greater elements so your original list will replace the left list. 另外,您可以考虑只删除较大的元素,这样您的原始列表将替换左侧的列表。
  • You must implement the join function, that insert all the elements of left and right (in that order) in mylist. 您必须实现join函数,该函数将mylist中的left和right的所有元素(按此顺序)插入。 You does not need to move the elements one by one, just manipulate the first and last pointers. 您不需要一个个地移动元素,只需操纵第一个和最后一个指针即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM