질서 정연 한 단일 체인 테이블 의 합병
33757 단어 싱글 체인 리스트
@ 저자: 장 해발
@Update: 2014-01-23
@Link: http://www.cnblogs.com/zhanghaiba/p/3531142.html
1 /*
2 *Author: ZhangHaiba
3 *Date: 2014-1-23
4 *File: sorted_list_merge.c
5 *
6 *a demo shows how to merge two sorted single linked list by
7 *creating a new list or in-place.
8 */
9
10 #include <stdio.h>
11 #include <stdbool.h>
12 #include <stdlib.h>
13 #define INF 0x7fffffff
14 #define CMD_LNE 128
15
16 typedef struct node* link;
17 typedef struct node {
18 int item;
19 link next;
20 }node;
21
22 //public
23 link NODE(int item, link next);
24 link list_create(int n);
25 link sorted_list_merge_create1(link list_src_a, link list_src_b);
26 link sorted_list_merge_create2(link list_src_a, link list_src_b);
27 link sorted_list_merge_in_place1(link list_src_a, link list_src_b);
28 link sorted_list_merge_in_place2(link list_src_a, link list_src_b);
29 void list_travel(link head);
30 void list_destroy(link head);
31 //private
32 //accept list without Head Node, and return list without Head Node as well
33 link sorted_list_merge_create_iter(link a, link b);
34 link sorted_list_merge_in_place_iter(link a, link b);
35 link sorted_list_merge_create_rec(link a, link b);
36 link sorted_list_merge_in_place_rec(link a, link b);
37
38
39 int main(void)
40 {
41 int len_a, len_b;
42
43 scanf("%d", &len_a);
44 link list_a = list_create(len_a);
45 printf("list_a travel: ");
46 list_travel(list_a);
47
48 scanf("%d", &len_b);
49 link list_b = list_create(len_b);
50 printf("list_b travel: ");
51 list_travel(list_b);
52
53 printf("create list_c by using(merging) list_a and list_b nodes.
");
54 //link list_c = sorted_list_merge_create1(list_a, list_b);
55 link list_c = sorted_list_merge_create2(list_a, list_b);
56 printf("list_c travel: ");
57 list_travel(list_c);
58
59 printf("merge list_c and list_a to list_d.
");
60 //link list_d = sorted_list_merge_in_place1(list_c, list_a);
61 link list_d = sorted_list_merge_in_place2(list_c, list_a);
62 printf("list_d travel: ");
63 list_travel(list_d);
64
65 list_c = list_a = NULL;
66 list_destroy(list_b);
67 printf("list_b destroyed!
");
68 list_destroy(list_d);
69 printf("list_d destroyed!
");
70 return 0;
71 }
72
73 link NODE(int item, link next)
74 {
75 link born = malloc(sizeof (node));
76 born->item = item;
77 born->next = next;
78 return born;
79 }
80
81 //tail insert
82 link list_create(int n)
83 {
84 int i, item;
85 link head = NODE(INF, NULL);
86 link tail = head;
87
88 for (i = 0; i < n; ++i) {
89 scanf("%d", &item);
90 tail->next = NODE(item, NULL);
91 tail = tail->next;
92 }
93 return head;
94 }
95
96 //Iterative implementation begin here
97 link sorted_list_merge_create_iter(link a, link b)
98 {
99 link tmp_head = NODE(INF, NULL);
100 link c = tmp_head; //c as tail pointer for the list_c
101
102 for (; a != NULL && b != NULL; c = c->next)
103 if (a->item < b->item)
104 c->next = NODE(a->item, NULL), a = a->next;
105 else
106 c->next = NODE(b->item, NULL), b = b->next;
107 for (; a != NULL; c = c->next, a = a->next)
108 c->next = NODE(a->item, NULL);
109 for (; b != NULL; c = c->next, b = b->next)
110 c->next = NODE(b->item, NULL);
111 link first = tmp_head->next;
112 free(tmp_head);
113 return first;
114 }
115
116 link sorted_list_merge_create1(link a, link b)
117 {
118 if (a == NULL || b == NULL)
119 return NULL;
120 return NODE(INF, sorted_list_merge_create_iter(a->next, b->next));
121 }
122
123 link sorted_list_merge_in_place_iter(link a, link b)
124 {
125 link tmp_head = NODE(INF, NULL);
126 link c = tmp_head; //c as tail pointer for the list_c
127
128 for (; a != NULL && b != NULL; c = c->next)
129 if (a->item < b->item)
130 c->next = a, a = a->next;
131 else
132 c->next = b, b = b->next;
133 c->next = a != NULL ? a : b; //link left ordered list
134 link first = tmp_head->next;
135 free(tmp_head);
136 return first;
137 }
138
139 link sorted_list_merge_in_place1(link a, link b)
140 {
141 if (a == NULL || b == NULL)
142 return NULL;
143 link head = NODE(INF, sorted_list_merge_in_place_iter(a->next, b->next));
144 free(a);
145 free(b);
146 return head;
147 }
148 //Iterative implementation end here
149
150
151 //Recursive implementation begin here
152 link sorted_list_merge_create_rec(link a, link b)
153 {
154 link first = NULL;
155
156 if (a == NULL) {
157 link tmp_head = NODE(INF, NULL);
158 link c = tmp_head; //c as tail pointer for left list
159 while (b != NULL) {
160 c->next = NODE(b->item, NULL);
161 c = c->next;
162 b = b->next;
163 }
164 link left = tmp_head->next;
165 free(tmp_head);
166 return left;
167 }
168 if (b == NULL) {
169 link tmp_head = NODE(INF, NULL);
170 link c = tmp_head; //c as tail pointer for left list
171 while (a != NULL) {
172 c->next = NODE(a->item, NULL);
173 c = c->next;
174 a = a->next;
175 }
176 link left = tmp_head->next;
177 free(tmp_head);
178 return left;
179 }
180 if (a->item < b->item) {
181 first = NODE(a->item, NULL);
182 first->next = sorted_list_merge_create_rec(a->next, b);
183 } else {
184 first = NODE(b->item, NULL);
185 first->next = sorted_list_merge_create_rec(b->next, a);
186 }
187 return first;
188 }
189
190 link sorted_list_merge_create2(link a, link b)
191 {
192 if (a == NULL || b == NULL)
193 return NULL;
194 return NODE(INF, sorted_list_merge_create_rec(a->next, b->next));
195 }
196
197 link sorted_list_merge_in_place_rec(link a, link b)
198 {
199 if (a == NULL)
200 return b;
201 if (b == NULL)
202 return a;
203 link first = NULL;
204 if (a->item < b->item) {
205 first = a;
206 first->next = sorted_list_merge_in_place_rec(a->next, b);
207 } else {
208 first = b;
209 first->next = sorted_list_merge_in_place_rec(a, b->next);
210 }
211 return first;
212 }
213
214 link sorted_list_merge_in_place2(link a, link b)
215 {
216 if (a == NULL || b == NULL)
217 return NULL;
218 link head = NODE(INF, sorted_list_merge_in_place_rec(a->next, b->next));
219 free(a);
220 free(b);
221 return head;
222 }
223 //Recursive implementation end here
224
225 void list_travel(link head)
226 {
227 for (head = head->next; head != NULL; head = head->next)
228 printf(head->next == NULL ? "%d
" : "%d ", head->item);
229 }
230
231 void list_destroy(link head)
232 {
233 head->next == NULL ? free(head) : list_destroy(head->next);
234 }
테스트 예시:
ZhangHaiba-MacBook-Pro:code apple$ ./a.out
6
30 53 65 77 88 99
list_a travel: 30 53 65 77 88 99
9
11 22 33 44 55 100 120 199 211
list_b travel: 11 22 33 44 55 100 120 199 211
create list_c by using(merging) list_a and list_b nodes.
list_c travel: 11 22 30 33 44 53 55 65 77 88 99 100 120 199 211
merge list_c and list_a to list_d.
list_d travel: 11 22 30 30 33 44 53 53 55 65 65 77 77 88 88 99 99 100 120 199 211
list_b destroyed!
list_d destroyed!
단일 체인 표 의 합병 으로 두 개의 인터페이스 (함수) 를 제공 합 니 다: sortedlist_merge_create () 와 sortedlist_merge_in_place()。비 현지 합병 과 현지 합병 에 각각 대응 하 다.
두 함수 가 각각 쓸모 가 있 고 그 자리 에서 합병 하지 않 고 새로운 링크 를 만 들 며 입력 한 두 개의 링크 는 계속 사용 할 수 있 습 니 다.
현지에서 합병 하면 입력 한 두 개의 링크 a 와 b 를 하나의 링크 c 로 합 쳐 합병 하면 a 와 b 는 논리 적 으로 존재 하지 않 습 니 다.
여기 서 작 동 하 는 링크 는 앞장 서 는 노드 의 단일 링크 이기 때문이다.
함수 의 재 활용 성 을 고려 하여 먼저 디자인 된 합병 함수 A: 앞장 서지 않 는 노드 의 링크 두 개 를 받 고 앞장 서지 않 는 노드 의 (새로운) 링크 를 되 돌려 줍 니 다.
앞장 서 는 노드 의 링크 는 앞장 서지 않 는 노드 의 링크 의 한정 (부분 집합) 일 뿐이다.
그래서 케이스 함수 포장 을 통 해 이전 단계 에 실 현 된 합병 함수 A 를 디자인 하면 선두 노드 의 단일 체인 표 합병 함수 B 를 실현 할 수 있다.
병합 함수 B: 두 개의 선두 노드 의 링크 를 받 고 선두 노드 의 (새) 링크 를 되 돌려 줍 니 다.링크 에 들 어 오 는 헤드 노드 가 비어 있 으 면 안 되 며, 그렇지 않 으 면 NULL 로 돌아 갑 니 다.
A 함 수 는 상기 실현 중의
sorted_list_merge_create_iter () 와 sortedlist_merge_create_rec()
sorted_list_merge_in_place_iter () 와 sortedlist_merge_in_place_rec()
다음은 실현 방법의 측면 에서 수직 대 비 를 한다.
(1) 반복 실현
교체 실현 에서 임시 헤드 노드 를 빌 렸 습 니 다. 그래 야 첫 번 째 노드 의 지침 first 를 저장 할 수 있 습 니 다. first 로 돌아 가기 전에 임시 헤드 노드 를 먼저 방출 할 수 있 습 니 다.
1) 비 현지 합병
만약 에 b 가 a 가 아직 끝나 지 않 았 다 면 a 의 나머지 를 새 링크 뒤에 순서대로 복사 합 니 다.마찬가지
2) 현지 합병
만약 에 b 가 a 가 아직 끝나 지 않 았 다 면 a 남 은 링크 를 tail 포인터 c 에 한 번 에 연결 하면 효율 이 높다 고 말 할 수 있다.마찬가지
(2) 귀속 실현
1) 비 현지 합병
만약 에 링크 a 가 비어 있 으 면 b 남 은 링크 를 복사 합 니 다 (임시 헤드 노드 를 통 해 이 루어 지고 left 로 돌아 가기 전에 임시 헤드 노드 를 방출 합 니 다).마찬가지
그렇지 않 으 면 작은 노드 를 선택 하여 현재 링크 의 루트 노드 로 복사 한 다음 에 나머지 링크 를 합 쳐 서브 링크 로 한다.
2) 현지 합병
링크 a 가 비어 있 으 면 링크 b 로 바로 돌아 갑 니 다.마찬가지
그렇지 않 으 면 비교적 작은 노드 를 현재 링크 의 루트 노드 로 선택 한 다음 에 나머지 링크 를 합 쳐 서브 링크 로 한다.
케이스 함수 에 대해 서 는 현지에서 합병 하지 않 으 면 할 말 이 없고 현지에서 합병 하기 전에 a 와 b 의 머리 노드 를 방출 해 야 합 니 다.
클 라 이언 트 프로그램 (주 함수) 에서 c 와 a 를 현지에서 합병 한 후에 c 와 a 를 NULL 로 설정 할 책임 이 있 습 니 다. 호출 자 는 이때 c 와 a 가 존재 하지 않 는 다 는 것 을 알 기 때 문 입 니 다.
소결: 단일 체인 표 의 비 현지 합병 과 현지 합병 은 모두 체인 표 의 '꼬리 삽입 법' 을 이용 하여 표를 만 들 었 다.차이 점 은 전 자 는 노드 를 생 성하 고 후 자 는 노드 에 연결 하 며 후자 의 효율 이 더욱 높다 는 것 이다.
\ # 이전 단계 로 돌아 가기
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
데이터 구조 상의 연습 (2) 싱글 체인 시트#include "stdafx.h" #include "stdlib.h" #include "malloc.h" #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.