基于无头节点的单链表的升序冒泡排序(C++实现)

由于基础代码的特殊(链表为无头链表),以下冒泡排序算法采用两种方式进行排序。首先对首节点往后的所有节点进行排序,这里使用的是对其索引顺序改变的方法。然后对首节点进行排序,只需要一次循环即可,这里使用的是对节点中的数值进行交换的方法。


  1 #include <iostream>
  2 using namespace std ;
  3
  4 #define ERROR -1
  5 #define CORRECT 1
  6
  7 //定义
  8 struct LNode {
  9     int data ;
 10     LNode *next ;
 11 } ;
 12 LNode *LinkList ;
 13
 14 //查找
 15 LNode *SearchLinkList (LNode *L , int i)
 16 {
 17     int j ;
 18     LNode *p ;
 19
 20     p = L ;
 21     j = 1 ;
 22     while (p &&j < i)
 23     {
 24         p = p -> next ;
 25         j++ ;
 26     }
 27     if (!p || j>i)
 28     {
 29         return (p) ;
 30     }
 31 }
 32
 33 //插入
 34 int InsertLinkList (LNode *L , int e , int i)
 35 {
 36     //在链表L中第i个位置插入元素e
 37     LNode *p , *s ;
 38     p = SearchLinkList (L , i-1) ;
 39     if (!p)
 40     {
 41         return (ERROR) ;
 42     }
 43     s = new LNode ;
 44     //节点插入L中
 45     s -> data = e ;
 46     s -> next = p -> next ;
 47     p -> next = s ;
 48
 49     return (CORRECT) ;
 50 }
 51
 52 //表单创建
 53 LNode *CreateLinkList (int *r , int n)
 54 {
 55     int j ;
 56     LNode *L , *p , *s ;
 57
 58     if (n <= 0)
 59     {
 60         return (NULL) ;
 61     }
 62     s = new LNode ;
 63     s -> data = r[1] ;
 64     s -> next = NULL ;
 65     L = s ;
 66     p = L ;
 67     for (j = 2 ; j <= n ; j++)
 68     {
 69         /*
 70         s = new LNode ;
 71         s -> data = r[j] ;
 72         s -> next = NULL ;
 73         p -> next = s;
 74         p = s ;
 75         */
 76
 77         InsertLinkList (L , r[j] , j) ;
 78     }
 79     return (L) ;
 80 }
 81
 82 //删除
 83 int DeleteLinkList (LNode *L , int i)
 84 {
 85     //在表中删除第i个位置
 86     int e ;
 87     LNode *p , *q ;
 88
 89     p = SearchLinkList (L , i-1) ;
 90     if (!p)
 91     {
 92         return (ERROR) ;
 93     }
 94     q = p -> next ;
 95     p -> next = p -> next -> next ;    //不可用q,因为q是用来指示将要删除的内存
 96     e = q -> data ;
 97     delete (q) ;
 98
 99     return (e) ;
100 }
101
102 //结果输出
103 int ShowLinkList (LNode *L)
104 {
105     LNode *p ;
106
107     if (!L)
108     {
109         return (ERROR) ;
110     }
111     p = L ;
112     while (p -> next)
113     {
114         cout << p -> data <<" " ;
115         p = p -> next ;
116     }
117     cout << p -> data << endl ;
118     return (CORRECT) ;
119 }
120
121 //升序排序(完全用指针操作,有bug)
122 int BubbleSortPoint (LNode *L)
123 {
124     LNode *HeadNode ;
125     HeadNode = new LNode ;
126
127     LNode *p ;
128     LNode *q ;
129
130     LNode *a1 ;
131     LNode *a2 ;
132     LNode *a3 ;
133     if (!L)
134     {
135         return (ERROR) ;
136     }
137
138     HeadNode -> next = L ;    //增加头节点
139
140     cout << "HeadNode ->next ->data = " <<HeadNode ->next->data << endl; //打印调试
141
142     /*由于链表L为无头节点链表,故先对首节点数据进行处理*/
143
144     for (p = HeadNode ; p -> next != NULL ; p = p -> next)
145     {
146         for (q = HeadNode; q -> next -> next != NULL ; q = q -> next)
147         {
148             /*节点指针*/
149             a1 = q -> next ;
150             a2 = q -> next -> next ;
151             a3 = q -> next -> next -> next ;
152
153             /*打印调试*/
154             cout << "a1 -> data = " <<a1->data << endl ;
155             cout << "a2 -> data = " <<a2->data << endl ;
156             if (a3!=NULL)
157             {
158                 cout << "a3 -> data = " <<a3->data << endl ;
159             }
160             else
161             {
162                 cout << "a3 -> data = NULL" <<endl ;
163             }
164
165             cout <<endl;
166
167             /*打印调试*/
168             if (a1 -> data > a2 -> data)
169             {
170                 /*节点交换*/
171                 q -> next = a2 ;
172                 a2 -> next = a1 ;
173                 a1 -> next = a3 ;
174             }
175         }
176     }
177
178     //对首节点进行处理
179     cout << "HeadNode -> next -> data = " << HeadNode -> next -> data << endl ;
180     p = L ;
181     L = HeadNode -> next ;
182     cout << "L -> data = " << L -> data << endl ;
183     cout << "L -> next -> data = " << L -> next ->data << endl ;
184     cout << "L -> next -> next -> data = " << L -> next -> next ->data << endl ;
185     cout << "L -> next -> next -> next -> data = " << L -> next -> next -> next ->data << endl ;
186     cout << "L -> next -> next ->next -> next -> data = " << L -> next -> next -> next -> next ->data << endl ;
187
188     return (CORRECT) ;
189 }
190
191 //升序冒泡排序(指针与data交换结合)
192 int BubbleSort (LNode *L)
193 {
194     LNode *p ;
195     LNode *q ;
196     int middleData ; //中间数据,用于实现首节点数据的沉底操作
197
198     /*用于节点索引顺序交换操作的指针定义*/
199     LNode *a1 ;
200     LNode *a2 ;
201     LNode *a3 ;
202
203     if (!L)
204     {
205         return (ERROR) ;
206     }
207
208
209     /*先用指针索引更改的方式排序首节点以后的元素*/
210
211     for (p = L ; p -> next != NULL ; p = p -> next)
212     {
213         for (q = L ; q -> next -> next != NULL ; q = q -> next)
214         {
215             /*节点指针*/
216             a1 = q -> next ;
217             a2 = q -> next -> next ;
218             a3 = q -> next -> next -> next ;
219
220             if (a1 -> data > a2 -> data)
221             {
222                 /*节点交换*/
223                 q -> next = a2 ;
224                 a2 -> next = a1 ;
225                 a1 -> next = a3 ;
226             }
227         }
228     }
229
230     /*再对首节点数据采取数值交换的方式使其沉底*/
231     p = L ;
232     while (p -> next)
233     {
234         if (p -> data > p -> next -> data)
235         {
236             middleData = p -> data ;
237             p -> data = p -> next -> data ;
238             p -> next -> data = middleData ;
239         }
240         p = p -> next ;
241     }
242
243     return (CORRECT) ;
244
245 }
246
247 int main (int argc , char * argv[])
248 {
249     int r[100] , i ,SampleNum , SearchPos , NewPos , NewItem , DelPos ;
250     LNode *p ;
251
252     cin >> SampleNum ;
253     for (i = 1 ; i <= SampleNum ; i++)
254     {
255         cin >> r[i] ;
256     }
257     LinkList = CreateLinkList (r , SampleNum) ;
258     ShowLinkList (LinkList) ;
259
260     cout << "冒泡排序:" << endl ;
261     BubbleSort (LinkList) ;
262     ShowLinkList (LinkList) ;
263
264     cin >> SearchPos ;
265     p = SearchLinkList (LinkList , SearchPos) ;
266     cout << p -> data << endl ;
267
268     cin >> NewPos ;
269     cin >> NewItem ;
270     InsertLinkList (LinkList , NewItem , NewPos) ;
271     ShowLinkList (LinkList) ;
272
273     cin >> DelPos ;
274     DeleteLinkList (LinkList , DelPos) ;
275     ShowLinkList (LinkList) ;
276
277     return 0;
278 }
时间: 2024-10-14 01:41:22

基于无头节点的单链表的升序冒泡排序(C++实现)的相关文章

基于数组实现的单链表(兼具Boost单元测试)

对于单链表,我们大多时候会用指针来实现(可参考基于指针实现的单链表).现在我们就来看看怎么用数组来实现单链表. 1. 定义单链表中结点的数据结构 1 typedef int ElementType; 2 class NodeType 3 { 4 public: 5 ElementType data; 6 int next; 7 }; 该结点包括了两个元素,其一是数据,另一个是指向下一个结点的"指针"(在这篇文章中实际上是指用于实现单链表的数组的下标.)  2. 定义一个的数组 1 co

数据结构 队列(带尾节点的单链表实现) 回顾练习

带尾节点的单链表队列 入队0(1) 出队0(1) 1 #!/usr/bin/env python3 2 3 class QueueUnderflow(ValueError): 4 pass 5 6 class Node(object): 7 def __init__(self, elem, next_=None): 8 self.elem = elem 9 self.next = next_ 10 11 #queue_list 12 class LQueue(object): 13 def __

带头节点的单链表的插入操作

1.偶然看到了十字链表的应用,想到之前在<数据结构与算法分析>的链表一章中,需要用多重表实现一个简单的查询功能.功能需求如下: “已知 学生 和 学校课程 总数 分别为 40000 和 2500,现在需要得到两份报告,一份显示每门课成注册的所有学生信息, 一份显示每个学生注册了哪些课程.” 显然可以用一个 40000 * 2500 个元素的二维数组来解决,但是每个学生选课数目很少,因此会浪费很多空间.因此选择十字链表来实现. 既然是链表,那么肯定要有插入操作,于是便有了本文.算是对功能实现前的

带头节点控制单链表之C语言实现

//  1.头.尾节点位置 //  2.链表 //  元素数量 #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <string.h> //链表节点信息: // //   1.数据域 //   2.指针域 #define TRUE     (1) #define FALSE    (0) #define ZERO     (0) #define ONLY_ONE (1)

带头节点的单链表

//带头结点的单链表 #include <iostream> #include <stdlib.h> using namespace std; typedef int ElemType; typedef struct Node { ElemType data; struct Node *next; }LNode,*LinkList; void InitList(LinkList *L); void Create_head(LinkList l); void Create_rear(

带头节点的单链表-------C语言实现

1 /***************************************************** 2 Author:Simon_Kly Version:0.1 Date:20170520 3 Description:带头接点的单链表 4 Mail:[email protected] 5 Funcion List: 6 *****************************************************/ 7 8 #include <stdio.h> 9 #

无头结点的单链表(C语言)

1.单链表: 在顺序表中,用一组地址连续的存储单元来一次存放线性表的结点,因此结点的逻辑顺序与物理顺序是一致的.但链表却不同,链表是用一组任意的存储单元来存放 线性表的结点,这组存储单元可以是连续的,也可以是非连续的,甚至是零散分布在内存的任何位置上.因此,链表中结点的逻辑顺序与物理顺序不一定相同.为了正确表示节点间的逻辑关系,必须在存储线性表的每个数据元素的同时,存储指示其后继结点的地址信息,这两部分信息共同构成了单链表结点的结构,如下图: 结点包括两个域,数据域用来存放结点的值,指针域用来存

【 C# 数据结构】(一) -------------------------- 泛型带头节点的单链表,双向链表实现

在编程领域,数据结构与算法向来都是提升编程能力的重点.而一般常见的数据结构是链表,栈,队列,树等.事实上C#也已经封装好了这些数据结构,在头文件 System.Collections.Generic 中,直接创建并调用其成员方法就行.不过我们学习当然要知其然,亦知其所以然. 本文实现的是链表中的单链表和双向链表,并且实现了一些基本方法 一. 定义一个链表接口 MyList 接口里声明了我们要实现的方法: interface MyList<T> { int GetLength(); //获取链表

使用带有头尾节点的单链表实现队列

package db; public class Queue<E> { /** * 内部类--单链表 * @author fightzhao * * @param <E> */ private static class Node<E> { public Node<E> next; public E data; public Node(E data, Node<E> next) { this.data = data; this.next = nex