我尝试使用冒泡排序算法对链接列表进行排序,方法是更改节点的引用。我搜索过很多书和互联网,但我发现排序方法可以改变节点之间信息部分的值。 我想要做的是通过改变列表的行进顺序进行排序,而不是它们之间的值。 这是我的代码。 PS:排序算法不起作用。 它不是合并排序列表的重复,因为它完全是另一种算法。
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#define LINESIZE 128
struct Student {
float medie;
char nrMatricol[10];
char *nume;
char facltate[6];
};
struct Nod{
Student stud;
Nod* next;
};
Nod* inserareNodEnd(Nod *l,Student st)
{
Nod *nou = (Nod*)malloc(sizeof(Nod));
nou->next = NULL;//NOU->NEXT=0
nou->stud = st;
if (!l) {
//lista este goala
return nou;
}
else
{
//lista contine un nod
Nod *t = l;
while (t->next) {
t = t->next;
}
t->next = nou;
return l;
}
}
float medieStudenti(Nod *lista) {
float suma=0;
int i=0;
Nod *aux=lista;
while (aux->next) {
aux = aux->next;
suma += aux->stud.medie;
i++;
}
return suma/i;
}
Nod *stergerePrimulNodLista(Nod *l,Student *st) {
if (l) {
Nod *aux = l;
l = l->next;
aux->next = NULL;
*st = aux->stud;
//aux->next = NULL;
free(aux);
}
return l;
}
Nod* sortareLista(Nod *l) {
Nod *i=l;
Nod *j=l;
Nod *aux=l;
Nod *min=l;
min = i;
while (i->next) {
if (i->stud.medie < min->stud.medie) {
min = i;
}
i = i->next;
}
i = l;
int n = 0;
while (i->next) {
j = i->next;
while (j->next) {
if (i->stud.medie > j->stud.medie) {
aux = i->next;
i->next = j->next;
j->next = aux;
}
j = j->next;
}
i = i->next;
}
return min;
//return l;
}
void dezalocare(Nod *lista) {
Nod *aux;
aux = lista;
while (aux->next) {
lista = aux->next;
free(aux->stud.nume);
free(aux);
aux = lista;
}
}
void main()
{
FILE *f;
Student s;
Nod *list=NULL;
f = fopen("fisier.txt", "r");
char fileBuff[LINESIZE], SEPARATORI[] = { "," };
char *token;
while (fgets(fileBuff, LINESIZE, f)) {
token = strtok(fileBuff, SEPARATORI);
strcpy(s.nrMatricol, token);
//extragere token nume student din aceeasi linie
//salvata in file Buff
token = strtok(NULL, SEPARATORI);
s.nume = (char*)malloc(sizeof(char)*strlen(token) + 1);
strcpy(s.nume, token);
token = strtok(NULL, SEPARATORI);
strcpy(s.facltate, token);
//extragere tokeni medie si conversia tokenului la float
token = strtok(NULL, SEPARATORI);
s.medie = atof(token);
list = inserareNodEnd(list, s);
printf("%s %s \n", s.nrMatricol, s.nume);
}
Nod *tmp = list;
while (tmp) {
printf("\nSe afiseaza din lista");
printf("%s %s \n", tmp->stud.nrMatricol, tmp->stud.nume);
tmp = tmp->next;
}
fclose(f);
//determinarea mediei pentru studentii din lista
float media = medieStudenti(list);
printf("\nMedia este %.2f", media);
//sortare lista dupa medie(cu modificarea adreselor de legatura)
//tema dezalocare lista
//tema dezalocari la nivel de aplicatie
printf("\nAcesta este Ionel %s %s \n", s.nrMatricol, s.nume);
// list = stergerePrimulNodLista(list, &s);
tmp = list;
while (tmp) {
printf("\nSe afiseaza din lista");
printf("%s %s \n", tmp->stud.nrMatricol, tmp->stud.nume);
tmp = tmp->next;
}
tmp = list;
while (tmp) {
printf("\nSe afiseaza lista sortata");
printf("%s %s \n", tmp->stud.nrMatricol, tmp->stud.nume);
tmp = tmp->next;
}
dezalocare(list);
}
答案 0 :(得分:0)
根据原始海报的要求,链表的冒泡排序示例。
更新 - 已删除<span class="error-message" ng-show="form1.phone.$dirty &&form1.phone.$invalid"></span>
<div id="characters">
<span>Characters left: {{maxLength - message.description.length}}</span>
,而是使用pnEnd(ptr到未排序列表的结尾)。
swap
答案 1 :(得分:0)
首先:bubblesort很糟糕。 对于链表,它更可怕...... [&#34;自然&#34;对链表进行排序的方法是merge-sort,因为拉链合并两个已排序的链表很容易]
对于冒泡排序,基本操作是:
#include <stdio.h>
struct node{
struct node *next;
int value;
};
struct node nodes[] =
{{ nodes+1, 9}
,{ nodes+2, 5}
,{ nodes+3, 0}
,{ nodes+4, 1}
,{ nodes+5, 4}
,{ nodes+6, 7}
,{ nodes+7, 2}
,{ nodes+8, 3}
,{ nodes+9, 8}
,{ NULL , 6}
};
void node_printlist(struct node *p) {
for ( ;p; p=p->next) {
printf("%d\n", p->value);
}
}
unsigned node_bubblepass(struct node **pp)
{
struct node *one, *two;
unsigned swaps;
for (swaps=0 ; one = *pp; pp=&(*pp)->next) {
two = one->next;
if(!two) break;
if(two->value >= one->value) continue;
/* wrong order: swap them*/
one->next = two->next;
two->next = one;
*pp = two;
swaps++;
}
return swaps;
}
void node_bubblesort(struct node **pp)
{
unsigned swaps;
do {
swaps = node_bubblepass(pp);
} while (swaps);
}
int main(void){
struct node *root =nodes;
printf("Original:\n");
node_printlist(root);
node_bubblesort(&root);
printf("Result:\n");
node_printlist(root);
return 0;
}
在内圈中更新(感谢@rcgldr),当我们点击之前已经被冒泡的物品时,我们可以停止向下冒泡。
struct node * node_bubblepass_2(struct node **pp, struct node *end)
{
struct node *one, *two;
for ( ; one = *pp; pp=&(*pp)->next) {
two = one->next;
if(two == end) break;
if(two->value >= one->value) continue;
/* wrong order: swap them*/
one->next = two->next;
two->next = one;
*pp = two;
}
return one;
}
void node_bubblesort_2(struct node **pp)
{
struct node *end = NULL;
do {
end = node_bubblepass_2(pp, end);
} while (*pp != end);
}