双方向リストのクイックソートにて
並び替えが以下のように上手くいかないです。
0 1 2 3 3 5 5 6 6 6 6 7 7 7 8 7 7 8 9 10 9
C
1#include<stdio.h> 2#include<stdlib.h> 3 4struct node { 5 int data; 6 struct node *prev; 7 struct node *next; 8}; 9 10 11void print_list(struct node *start); 12void sort_list(struct node **arg_s, struct node **arg_e); 13void swap(struct node **left, struct node **right); 14void trade(struct node **l, struct node **r,struct node **s , struct node **e); 15 16#define MAX 1000 17 18int main(void) { 19 struct node *start, *end, *new,*temp; 20 int i; 21 22 start = end = NULL; 23 for (i = 0; i < MAX * 5; i++) { 24 new = malloc(sizeof(struct node)); 25 if (new == NULL) { 26 fprintf(stderr, "メモリ割り当て失敗\n"); 27 // ここで適切なクリーンアップを行う 28 exit(EXIT_FAILURE); 29 } 30 new->data = rand() % MAX; 31 new->prev = new->next = NULL; 32 33 if (start == NULL) { 34 start = end = new; 35 } else { 36 end->next = new; 37 new->prev = end; 38 end = end->next; 39 } 40 } 41 42 43 printf("ソート前:\n"); 44 print_list(start); 45 46 sort_list(&start, &end); 47 48 printf("ソート後:\n"); 49 print_list(start); 50 51 // メモリの解放処理 52 while (start != NULL) { 53 temp = start; 54 start = start->next; 55 free(temp); 56 } 57 58 return 0; 59} 60 61void print_list(struct node *start) 62{ 63 struct node *p; 64 65 p=start; 66 while(p!=NULL) 67 { 68 printf("%d ",p->data); 69 p=p->next; 70 } 71 printf("\n"); 72} 73 74void sort_list(struct node **arg_s,struct node **arg_e) 75{ 76 struct node *start,*end,*left,*right,*s1,*s2,*e1,*e2; 77 int pivot; 78 79//引数を普通のポインタ型に変える 80 start = *arg_s; 81 end =*arg_e; 82 83 left =start; 84 right =end; 85 86 //基準値を決定する。 87 pivot=left->data; 88 89 while(left!=right&&left->prev!=right) 90 { 91 //pivot以上が出るまで繰り返す。 92 while(left->data < pivot) 93 { 94 left=left->next; 95 } 96 97 //pivot未満が出るまで繰り返す。 98 while(right->data >pivot) 99 { 100 right=right->prev; 101 } 102 103 if(left->prev!=right&&left!=right) 104 { 105 //leftとrightを交換する。 106 trade(&left,&right,&start,&end); 107 //nextを代入する。 108 left=left->next; 109 right=right->prev; 110 } 111 } 112 113 s2=right->next; 114 e1=right; 115 116 s1=start; 117 e1->next=NULL; 118 e2=end; 119 e2->next=NULL; 120 121 122 if(s1!=e1) 123 { 124 sort_list(&s1,&e1); 125 } 126 if(s2!=e2) 127 { 128 sort_list(&s2,&e2); 129 } 130 131 //連結し直す。 132 e1->next=s2; 133 s2->prev=e1; 134 135 //戻り値を設定する 136 *arg_s=s1; 137 *arg_e=e2; 138} 139 140 141//leftとrightを交換する関数。 142void trade(struct node **l, struct node **r,struct node **s , struct node **e) 143{ 144 struct node *start,*end,*left,*right; 145 146 //引数を普通のポインタ型に変える 147 start = *s; 148 end =*e; 149 left =*l; 150 right =*r; 151 152 if(left == start) 153 { 154 start = right; 155 } 156 else 157 { 158 left->prev->next = right; 159 } 160 161 // 後側要素を参照していたprevが、前側の要素を参照するように変更 162 if(right == end) 163 { 164 end = left; 165 } 166 else 167 { 168 right->next->prev = left; 169 } 170 171 // start/endに関係ない部分を交換する 172 left->next->prev = right; 173 swap(&left->next, &right->next); 174 right->prev->next = left; 175 swap(&left->prev, &right->prev); 176 swap(&left, &right); 177 178 *l=left; 179 *r=right; 180 *s=start; 181 *e=end; 182} 183 184// 構造体のポインタ同士を交換する関数 185void swap(struct node **left, struct node **right) 186{ 187 struct node *tmp; 188 189 tmp = *left; 190 *left = *right; 191 *right = tmp; 192} 193
回答1件
あなたの回答
tips
プレビュー