1 //有序链表(升序)在一个有序链表中寻找一个集合成员(用有序链表表示集合,
2 //集合成员可以无限增加)
3
4 //基于有序链表表示集合的结构定义
5 typedef int DataType;//假定集合元素的数据类型为int型
6 typedef struct node//集合的结点定义
7 {
8 DataType data;//每个成员的数据
9 struct node *link;//链接指针
10 } SetNode;
11
12 typedef struct LinkSet//集合的定义
13 {
14 SetNode *first, *last;//表头、表尾指针
15 };
16
17
18 //集合的查找算法Contains是最常用的集合操作,它判断一个元素x是否存在于集合中。
19 //实际是,在一个有序链表中顺序检测过程:从链表首元结点开始,沿链表查找,直到找到这个元素或
20 //遇到大于这个元素的一个元素。若找到,则查找成功该元素在集合中;否则查找失败,元素不在此集合
21 SetNode *Contains(LinkSet& S, DataType x)
22 {//如果x是集合S的成员,则函数返回与x匹配的集合结点地址,否则返回NULL
23 SetNode *p = S.first->link;//链的扫描指针
24 while(p != NULL && p->data < x)//循链搜索
25 p=p->link;
26 if(p != NULL && p->data == x)//找到
27 return p;
28 else
29 return NULL;//未找到
30 }
31
32 //集合的插入指定算法。把一个新元素x插入集合中,算法先查找x插入位置。如果找到x则不能插入;
33 //否则插入在刚刚大于x的元素前面。这时必须用一个只真pre记忆p的前趋结点地址,
34 //新元素插入在pre与p中间
35
36 //集合addMember算法实现
37 int addMember(LinkSet& S, DataType x)
38 {
39 //把新元素x加入到集合之中。若集合中已有此元素,则函数返回0,否则函数返回1
40 SetNode *p = S.first->link;//p是扫描指针
41 SetNode *pre = S.first;//pre是p的前趋
42 while(p != NULL && p->data < x)//循链扫描
43 {
44 pre = p;
45 p = p->link;
46 }
47 if(p != NULL && p->data == x)//集合中已有此元素,不插入
48 return 0;
49 SetNode *q = new SetNode;//创建值为x的结点,用q指示
50 if(!q)
51 {cerr<<"存储分配失败!\n"; exit(1);}
52 q->data = x;//链入
53 q->link = p;//链入
54 pre->link = q;//链入
55 if(p == 0)//链到链尾时改链尾指针 if(!p)
56 S.last = q;
57 return 1;
58 }
59 //集合删除指定元素算法。先搜索删除结点位置。若未找到这个元素,则不能删除;否则将被删元素所在
60 //结点从链中摘下,需一个指针pre记忆p的前趋结点地址
61
62 //集合delMenber算法实现
63 int delMember(LinkSet& S, DataType x)
64 {//把集合中x元素删去。若集合不空且元素x在集合中,则函数返回true,否则返回0
65 SetNode *p = S.first->link;
66 SetNode *pre = S.first;
67 while(p != NULL && p->data < x)//循链扫描
68 {
69 pre = p;
70 p = p->link;
71 }
72 if(p != NULL && p->data == x)//找到,可以删除结点p
73 {
74 pre->link = p->link;//重新链接,从链上摘下p
75 if(p == S.last)//删去链尾时改链尾结点
76 S.last = pre;
77 delete p;//删除含x结点
78 return 1;//删除成功
79 }
80 else
81 return 0;//集合中无此元素,不能删除
82 }
83
83
84 //集合并运算‘ 合并两个有序链表并消除重复元素。
85 //需要对两个有序链表检测,当两个链表都未检测完时比较对应元素的值,把小的插
86 //入到结果链表中
87 //当其中有一个链表检测完时八零一个链表复制到结果链表中。
88
89 //集合Merge算法
90 void Merge(LinkList& LA, LinkList&LB, LinkSet& LC)
91 {//求集合LA与集合LB的并,结果通过LC返回,要求LC已存在且为空
92 SetNode *pa = LA.first->link;//LA集合链表扫描指针
93 SetNode *pb = LB.first->link;//LB集合链表扫描指针
94 SetNode *p, *pc = LC.first;//结果链表的存放指针
95 while(pa != NULL && pb != NULL)//两个集合都未检测完
96 {
97 if(pa->data <= pb->data)//LA集合中元素小或相等
98 {
99 pc->link = new SetNode;
100 if(!pc->link)
101 {cerr<<"存储分配失败!\n"; exit(1);}
102 pc->link->data = pa->data;//LA集合中的元素链入LC
103 pa = pa->link; //循链LA
104 if(pa->data == pb->data)//LA集合元素与LB元素相等
105 pb = pb->link;//循链LB
106 }
107 else//LB集合中元素值小
108 {
109 pc->link = new SetNode;
110 if(!pc->link){cerr<<"存储分配失败!\n"; exit(i);}
111 pc->link->data = pb->data;//LB集合中元素链入LC中
112 pb = pb->link;//循链LB
113 }
114 pc = pc->link;//LC循链指向下一个应存放的空间
115 }
116 p = (pa != NULL)? pa : pb;//处理未处理完的集合
117 while(p != NULL) //向结果链表中逐个复制
118 {
119 pc->link = new SetNode;
120 if(!pc->link){cerr<<"存储分配失败!\n"; exit(i);}
121 pc->link->data = p->data;
122 pc = pc->link;
123 p = p->link;
124 }
125 pc->link = NULL; //结果链表收尾
126 LC.last = pc;
127 }
128 //交运算
129 void Intersect(LinkList& LA, LinkList&LB, LinkSet& LC)
130 {
131 SetNode *pa = LA.first->link;//LA集合链表扫描指针
132 SetNode *pb = LB.first->link;//LA集合链表扫描指针
133 SetNode *pc = LC.first;
134 while(pa != NULL && pb != NULL)
135 {
136 if(pa->data <= pb->data)
137 {
138 if(pa->data == pb->data)
139 {
140 pc->link = new SetNode;
141 if(!pc->link){cerr<<"存储分配失败!\n"; exit(1);}
142 pc->link->data = pa->data;
143 pa = pa->link;
144 pb = pb->link;
145 }
146 else
147 pa = pa->link;
148 }
149 else
150 pb = pb->link;
151 pc = pc->link;
152 }
153 p = (pa == NULL) ? pa : pb;
154 while(p == NULL)
155 {
156 pc->link = NULL;
157 LC.last = pc;
158 }
159 }
160 //差运算
161 void SetDifference(LinkList& LA, LinkList&LB, LinkSet& LC)
162 {
163 SetNode *pa = LA.first->link;
164 SetNode *pb = LB.first->link;
165 SetNode *pc = LC.first;
166 while(pa != NULL && pb!= NULL)
167 {
168 if(pa->data < pb->data)
169 {
170 pc->link = new SetNode;
171 if(!pc->link){cerr<<"存储分配失败!\n"; exit(1);}
172 pc->link->data = pa->data;
173 pa = pa->link;
174 }
175 else if(pa->data == pb->data)
176 {
177 pa = pa->link;
178 pb = pb->link;
179 }
180 else
181 {
182 pc->link->data = pb->data;
183 pb = pb->link;
184 }
185 pc = pc->link;
186 }
187 p = (pa != NULL) ? pa : pb;
188 while(p != NULL) //向结果链表中逐个复制
189 {
190 pc->link = new SetNode;
191 if(!pc->link){cerr<<"存储分配失败!\n"; exit(i);}
192 pc->link->data = p->data;
193 pc = pc->link;
194 p = p->link;
195 }
196 pc->link = NULL; //结果链表收尾
197 LC.last = pc;
198 }