问题描述:
(1)合并两顺序表表为一个仍递增的表;
(2)合并两顺序表为一个递减的表;
(3)求出A,B集合的交集,并放在A中;仍旧使用A中的结点;
(4)找出在A中,不在B中的元素,保存在A中。
/
代码实现:
001 | #include <stdio.h> |
002 | #include <string.h> |
003 | #include <stdlib.h> |
004 | #define Status int |
005 | #define ERROR 0 |
006 | #define OK 1 |
007 | typedef struct Student |
008 | { |
009 | int number; |
010 | char name[20]; |
011 | }Student; |
012 | typedef struct LNode |
013 | { |
014 | Student student; |
015 | LNode *next,*prior; |
016 | }LNode,*LinkList; |
017 |
018 | Status Link(LinkList &L) |
019 | { |
020 | //创建空表头; |
021 | L = new LNode;L->next=NULL; |
022 | if (!L) return ERROR; |
023 | return OK; |
024 | } |
025 |
026 | int ListInsert(LinkList &L, int n) |
027 | { |
028 | //前插法创建含n个元素的单链表; 从头结点输出时会逆序; |
029 | printf ( "请输入第n个数字元素:\n" ); |
030 | for ( int i=0;i<n;i++) |
031 | { |
032 | LinkList p = new LNode; |
033 | if (!p) return ERROR; |
034 | int t; |
035 | scanf ( "%d" ,&t); |
036 | p->student.number=t; |
037 |
038 | //将新生成的元素前插法插入; |
039 | p->next=L->next; |
040 | L->next = p; |
041 | } |
042 | printf ( "此单链表建立完毕!\n" ); |
043 | return OK; |
044 | } |
045 |
046 | int ListInsert2(LinkList &L, int n) |
047 | { |
048 | //后插法创建单链表; 从头结点输出时是按照正常顺序。 |
049 | printf ( "请输入第n个数字元素:\n" ); |
050 | LinkList r = L; |
051 | for ( int i=0;i<n;i++) |
052 | { |
053 | LinkList p = new LNode; |
054 | if (!p) return ERROR; |
055 | int t; |
056 | scanf ( "%d" ,&t); |
057 | p->student.number = t; |
058 | r->next = p;p->next=NULL; |
059 | r = p; |
060 | } |
061 | printf ( "此单链表建立完毕!\n" ); |
062 | return OK; |
063 | } |
064 |
065 | //合并链表的时候,已经将插入链表的操作覆盖了。 |
066 | //这里的插入操作可以另写函数来进行调用,但也可以直接在此函数内部实现; |
067 | void HeBing1(LinkList L1,LinkList L2,LinkList &L3) |
068 | { |
069 | printf ( "这是算法设计(1):\n" ); |
070 | //合并的链表与原链表同增减; |
071 | LinkList pa,pb,pc; |
072 | L3=L1; |
073 | pa=L1->next;pc=L1;pb=L2->next; |
074 | while (pa && pb) |
075 | { |
076 | if ((pa->student.number) < (pb->student.number)) |
077 | {pc->next=pa;pc=pa;pa=pa->next;} |
078 | else |
079 | {pc->next=pb;pc=pb;pb=pb->next;} |
080 | } |
081 | pc->next= pa ?pa:pb; delete L2; |
082 | printf ( "合并链表完毕!\n" ); |
083 | } |
084 |
085 | void HeBing2(LinkList &L1,LinkList &L2,LinkList &L3) |
086 | { |
087 | printf ( "这是算法设计(2):\n" ); |
088 | //合并的链表与原链表不同增减; |
089 | LinkList pa,pb,pc; |
090 | L3=L1; |
091 | pa=L1->next;pc=L1;pb=L2->next; |
092 | pc->next=NULL; //这里一定要注意,将pc的下个结点制空,而且pc的下个结点的地址已经给了pa保存; |
093 | while (pa && pb) |
094 | { |
095 | LinkList r ; |
096 | //这里注意需要先保存pa的下个结点(next)的指针。 |
097 | if ((pa->student.number)<(pb->student.number)) |
098 | {r=pa->next; pa->next=pc->next;pc->next=pa; pa=r;} |
099 | else |
100 | {r=pb->next; pb->next=pc->next;pc->next=pb; pb=r;} |
101 | } |
102 |
103 | LinkList r; |
104 | if (!pa) r=pb; |
105 | else r=pa; |
106 | while (r) |
107 | { |
108 | //之后再将剩余的结点,前插法进入L1(pc)链表中; |
109 | LinkList t; |
110 | t=r->next; |
111 | r->next=pc->next; pc->next=r; |
112 | r=t; |
113 | } |
114 | printf ( "合并链表完毕!\n" ); |
115 | } |
116 | int Find( int x,LinkList L) |
117 | { |
118 | //找到返回1,没有返回0; |
119 | int flag=0; |
120 | LinkList p = L->next; |
121 | while (p) |
122 | { |
123 | if (p->student.number == x) |
124 | {flag=1; break ;} |
125 | p=p->next; |
126 | } |
127 | return flag; |
128 | } |
129 | void HeBing3(LinkList L1,LinkList L2,LinkList &L3) |
130 | { |
131 | //仍以递增顺序,合并两表中共有的元素; 与算法(1)基本相同; |
132 | //这个函数需要另一个在链表中查找元素student的操作,找到返回1,没有返回0; |
133 | printf ( "这是算法设计(3):\n" ); |
134 | LinkList pa,pb,pc; |
135 | pa=L1->next;pb=L2->next; |
136 | L3=L1; pc=L1; |
137 | |
138 | while (pa) |
139 | { |
140 | int t=pa->student.number; |
141 | int flag=Find(t,L2); |
142 | if (flag) |
143 | {pc->next = pa;pc=pa;} |
144 | /*一定要注意,这里需要更改的是p->next的值,改pa的值是没用的,因为pc与L1指向的是同一段内存空间, |
145 | 但是pc本身的改变与L1却无任何关系!*/ |
146 | pa = pa->next; |
147 | } |
148 | pc->next=NULL; |
149 | } |
150 | void Print(LinkList &L) |
151 | { |
152 | //输出此合成链表的值; |
153 | LinkList r=L->next; |
154 | if (!r) printf ( "这是一个空表!" ); |
155 | while (r) |
156 | { |
157 | printf ( "%d " ,r->student.number); |
158 | r=r->next; |
159 | } |
160 | |
161 | printf ( "\n此链表输出完毕!\n" ); |
162 | } |
163 | void HeBing4(LinkList L1,LinkList L2,LinkList L3) |
164 | { |
165 | //将存在于A中,但不属于B的元素构成一个链表,保存在A中; |
166 | LinkList pa,pb,pc; |
167 | pa=L1->next; |
168 | pb=L2->next; |
169 | L3=L1;pc=L3; |
170 | while (pa) |
171 | { |
172 | int t=pa->student.number; |
173 | int flag=Find(t,L2); |
174 | //这里如果找到的话返回1; |
175 | if (!flag) |
176 | {pc->next=pa; pc=pa;} |
177 | pa=pa->next; |
178 | } |
179 | pc->next=NULL; |
180 | } |
181 |
182 | int main() |
183 | { |
184 | /*freopen("in.tet","r",stdin);*/ |
185 | int N,i,j,k; |
186 | LinkList L1,L2; |
187 | printf ( "请输入第一个链表有多少个元素:\n" ); scanf ( "%d" ,&N); |
188 | Link(L1);ListInsert2(L1,N); //这里创建链表使用后插法,来保证从低到高的顺序。 |
189 | printf ( "请输入第二个链表有多少个元素:\n" ); scanf ( "%d" ,&N); |
190 | Link(L2);ListInsert2(L2,N); |
191 | //创建两个单链表; |
192 |
193 | LinkList L3; //L3也指向L1的空间; |
194 | L3 = L1; |
195 |
196 | |
197 |
198 | /*合并两表为一个仍递增的表; |
199 | HeBing1(L1,L2,L3);Print(L3);*/ |
200 |
201 | /*合并两表为一个递减的表; |
202 | HeBing2(L1,L2,L3);Print(L3);*/ |
203 |
204 | /*求出A,B集合的交集,并放在A中; |
205 | HeBing3(L1,L2,L3);Print(L3);*/ |
206 |
207 | /*找出在A中,不在B中的元素,保存在A中; |
208 | HeBing4(L1,L2,L3);Print(L3);*/ |
209 |
210 | system ( "pause" ); |
211 | return 0; |
212 | } |