【问题标题】:Quicksort on Single Linked list单链表上的快速排序
【发布时间】:2015-02-10 15:20:12
【问题描述】:

我正在尝试为单链表上的 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;
}

【问题讨论】:

  • 快速排序依赖于列表不提供的可索引搜索。我不相信对链表进行快速排序有意义。
  • 链表不是一种适合快速排序的结构。请参阅此问题以获取替代方案stackoverflow.com/questions/1525117/…
  • char passwort[]; 无效
  • 单链表不能轻松快速排序,因为您需要双向遍历(而不仅仅是向前)。

标签: c list quicksort


【解决方案1】:

链表上的快速排序算法的总体思路是:

1 - 要选择一个主键,在您的情况下,您选择列表中的最后一个键。

2 - 将元素列表拆分为 2 个子列表:一个具有元素 = 枢轴(或 >)。您正在左右调用此列表。

3 - 对左右列表进行排序。这是递归部分:您使用快速排序对每个子列表进行排序,除非列表为空或只有一个元素。

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);
}

注意事项:

  • 我将pivot 更改为pivotKey,您只需要知道拆分列表的键即可。它甚至可能是一个不存在的键(例如,第一个和最后一个之间的平均值)
  • 基于上述,您必须创建分区函数,记住在从中获取元素并将它们插入到一个子列表中时更新原始列表。分区后您的原始列表将为空。或者,您可以想办法只删除较大的元素,以便您的原始列表将替换左侧列表。
  • 您必须实现连接功能,即在 mylist 中插入左右的所有元素(按此顺序)。您无需逐个移动元素,只需操作第一个和最后一个指针即可。

【讨论】:

    猜你喜欢
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2021-07-30
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    相关资源
    最近更新 更多