ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:22.44KB ,
资源ID:8157148      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8157148.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(数据结构单链表排序及通用排序模板.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

数据结构单链表排序及通用排序模板.docx

1、数据结构单链表排序及通用排序模板数据结构单链表排序昨天晚上写了个单链表排序功能的函数,没想到数据结构课只是过了一学期,写单链表数据结构的函数就遇到太多问题。唉,老师,我对不起你啊。我所要写的函数的程序是以单链表结构进行组织,无空头节点。要求可以按节点里的某个属性作为key大小排序。最开始,我并没回想到这个单链表交换位置,需要以指针进行移动。事实上,潜意识认为,只要将指针的值进行交换,即可(完全忘了单链表的知识了)。因为很自然的想成,链表是通过指针进行寻找节点的,交换了指针,就相当于交换节点顺序。貌似没有问题,所以我编写了如下函数(为了卖弄下,我还挑了个麻烦的快速排序方法,而不是后来简单的冒泡排

2、序):void QuickSort(struct book *head_book,int low,int high) static int count=1; int i=low,j=high; struct book *temp_ptr_book,*iptr_book,*jptr_book; temp_ptr_book=GetPtr_book(head_book,low); iptr_book=GetPtr_book(head_book,i); jptr_book=GetPtr_book(head_book,j); if(ij) while(ij) while (i=GetKey(jptr_b

3、ook) jptr_book=GetPtr_book(head_book,j);j- if(ij)iptr_book=jptr_book;i+; while (ij&GetKey(temp_ptr_book)GetKey(iptr_book) iptr_book=GetPtr_book(head_book,i);i+; if(ij)jptr_book=iptr_book;j-; iptr_book=temp_ptr_book; QuickSort(head_book,low,i-1); QuickSort(head_book,i+1,high); 运行结果却发现根本没有排序。因为上面的想法是大

4、错的,我将指针的值进行交换,并未改变节点的交换。指针的值是一个地址,交换值,只改变了指针所指向的是那个节点,但节点之间是靠指针联系的,交换指针值,根本没有任何作用。链表还是那个链表,一点也没有改变。那么就对节点进行修改就好了。确实这样做了,写了个类似拷贝构造函数,但是测试还是有问题,为什么?因为节点本身是有指向下一个节点的指针的,交换后怎么修改指针呢?顺着想下去,是不是可以这样想,我不改变链表节点的本身的顺序(即指向下一个节点的指针的值不改变),把节点的值进行交换(赋值),这样也是进行排序了。但是无奈能力太差,不知哪里写的有问题,测试结果出现指针异常。(即使成功如果节点数据太多,拷贝过去这样的

5、时间代价也是极大的!最后有解决方法比这样更好,所以就没去再找这个问题的原因,但从似乎逻辑上这样是可行的。)实在厌烦了,还是先试试简单的冒泡排序吧。但是没想到冒泡排序也出现了问题。记得学单链表的时候,交换节点只要一定顺序三次赋值就可以了,但是测试结果,排序结果第一遍就没走完,数据竟然遗失了。又得仔细找原因,后来才发现,一般冒泡排序,是针对基本数据类型或对象的,指针冒泡有些细节仍然要注意:每轮冒泡都是从头节点开始的,但是头节点可能会改变呀。但是我们每次冒泡是都是直接赋值最开始的那个头节点,这无疑会出现问题。普遍冒泡排序方法如下:/冒泡排序template void BubbleSort(sortl

6、ist &table) int i=1;int finish=0; cout冒泡排序结果:n; cout初始序列:;table.Show();coutendl; while(itable.CurrentSize&!finish) finish=1; /交换标志 for(int j=0;jtable.Arrj+1.GetKey() table.Swap(table.Arrj,table.Arrj+1); finish=0; /已交换 cout第i趟结果:; table.Show();coutendl; i+; for(int j=0;jbook_next=head_book; struct bo

7、ok *tail=NULL; /struct book *j1_ptr_book=head_book-book_next; while(NullH_book-book_next!=tail&!finish) finish=1; /交换标志 struct book *pre_book=NullH_book; struct book *cur_book=pre_book-book_next; while(cur_book!=tail&cur_book-book_next!=tail) if(GetKey(cur_book)book_next) pre_book-book_next=cur_book

8、-book_next; cur_book-book_next=cur_book-book_next-book_next; pre_book-book_next-book_next=cur_book; finish=0; /已交换 pre_book=pre_book-book_next; cur_book=pre_book-book_next; tail=cur_book; return NullH_book-book_next; 貌似问题解决了,但是这里只给出了冒泡排序,我们知道冒泡排序算法的时间上界为O(n2),即使,我增加了交换标志,可以改进一些,但是我们仍然像可不可以有更好的方法提高排序

9、效率。你也知道当然存在更好的算法,比如之前的快速排序,此外还有:直接插入排序,简单选择排序,堆排序,二路归并排序等等。我们是不是能够也对单链表排序呢?但是有一个问题,还是指针问题,冒泡是对相邻的节点交换,指针的交换就很麻烦了,还要多设置一个前一个节点的指针。那么,快速排序呢,是不相邻的节点的赋值(交换),这样的复杂过程,需要设置几个指针,需要怎样移动,要考虑哪些情况。堆排序情况是怎样的?归并排序又要怎样写?也许是有办法的,但想想也很麻烦,单链表操作实在很不好使用这些排序。是不是真的无法排序呢?办法还是有的。能不能利用已经写过的这些函数进行排序?教材有这些方法的关键代码,课设时也实现过了,但是是

10、对输入的整数,装入一个数组进行排序的,链表节点型的数据怎么排序?其实,回到最开始的错误想法来看,可以解决这个问题。如果我存放的是指针数组,每个指针指向链表的一个节点。可以通过指针找到节点,比较key,再对指针数组进行排序,这样就实现了对节点的排序。当然只进行这一步,肯定还是错误的,我们还是没对链表进行改变。所以,最后一步就是,在排好序的基础上,走一轮,将指针的指向的节点看成是独立的节点,修改它的属性中的指向下一节点的指针值为当前数组指针的后一个数组指针。这样就重新得到了一个单链表。唉,用进废退,是不变的法则啊,本以为数据结构学的还可以,现在好久不用了就将数据结构的特点给遗忘了。现在用JAVA,

11、C#,不写C+了指针都用不熟了,经常报错,用C里面的部分方法也出现错误。花了这么久终于算是解决了。附: 通用排序模板#include#includeusing namespace std;const int MaxSize=100;templateclass element template friend class sortlist;private: Type key; /数据元素关键字public: element():key(0) /构造函数 Type GetKey()return key; /取关键字 void setKey(const Type k)key=k; /修改关键字 ele

12、ment & operator =(element&x)key=x.key;return *this;/赋值,重载运算符=;templateclass sortlist / template friend void QuickSort(sortlist &table,int low,int high);也可以 friend void InsertionSort(sortlist &table); /直接插入排序 friend void BubbleSort(sortlist &table); /冒泡排序 friend void SelectSort(sortlist &table); /简单选

13、择排序 friend void QuickSort(sortlist &table,int low,int high); /快速排序 template friend class MaxHeap; /堆 friend void HeapSort(sortlist &table); /堆排序 friend void merge(sortlist &sourceTable,sortlist & mergedTable, const int left,const int mid,const int right); /归并 friend void MergePass(sortlist &sourceTa

14、ble,sortlist & mergedTable, const int len); /一趟归并 friend void MergeSort(sortlist &table); /两路归并public: element *Arr; /存储数据元素的向量 int CurrentSize; /数据表中的元素个数 sortlist():CurrentSize(0)Arr=new elementMaxSize;/构造函数 sortlist(const sortlist &sl) /拷贝构造函数 Arr=new elementMaxSize;CurrentSize=sl.CurrentSize; fo

15、r(int i=0;iCurrentSize;i+) Arri=sl.Arri; sortlist()delete Arr;/析构函数 void Swap(element& x,element & y) /交换x和y element temp=x;x=y;y=temp; void Insert(const Type k)ArrCurrentSize.setKey(k); CurrentSize+; /插入k void Show() /显示数据元素 for(int i=0;iCurrentSize;i+) coutArri.GetKey() ; ;/直接插入排序-使用监视哨改进需要将第一个空出来

16、,此处不便于其他排序算法的使用,所以不使用template void InsertionSort(sortlist &table) element temp; cout直接插入排序结果:n; cout初始序列:;table.Show();coutendl; int j; for(int i=1;i=0&temp.GetKey()table.Arrj-1.GetKey() table.Arrj=table.Arrj-1; j-; table.Arrj=temp; cout第i趟结果:; table.Show();coutendl; /冒泡排序template void BubbleSort(so

17、rtlist &table) int i=1;int finish=0; cout冒泡排序结果:n; cout初始序列:;table.Show();coutendl; while(itable.CurrentSize&!finish) finish=1; /交换标志 for(int j=0;jtable.Arrj+1.GetKey() table.Swap(table.Arrj,table.Arrj+1); finish=0; /已交换 cout第i趟结果:; table.Show();coutendl; i+; /简单选择排序templatevoid SelectSort(sortlist

18、&table) int k; cout简单选择排序结果:n; cout初始序列:;table.Show();coutendl; for(int i=0;itable.CurrentSize-1;i+) k=i; for(int j=i+1;jtable.CurrentSize;j+) if(table.Arrj.GetKey()table.Arrk.GetKey() k=j; /当前最小关键字的位置 if(k!=i) table.Swap(table.Arri,table.Arrk); cout第i+1趟结果:; table.Show();coutendl; /快速排序template cla

19、ss QSortpublic: void QuickSort(sortlist &table,int low,int high);templatevoid QSort:QuickSort(sortlist &table,int low,int high) static int count=1; if(count=1) cout快速排序结果:n; cout初始序列:;table.Show();coutendl; int i=low,j=high; elementtemp=table.Arrlow;/ 取区间第一个位置为基准位置 if(ij) while(ij) while(ij&temp.Get

20、Key()table.Arrj.GetKey() j-; if(ij)table.Arri=table.Arrj;i+; while(i=table.Arri.GetKey()i+; if(ij)table.Arrj=table.Arri;j-; table.Arri=temp; /基准元素归为 cout第count趟结果:;table.Show();coutendl;count+; QuickSort(table,low,i-1); /左区间递归快速排序 QuickSort(table,i+1,high); /右区间递归快速排序 /堆排序templateclass MaxHeappublic

21、: MaxHeap(int maxSize); /构造函数,建立空堆 MaxHeap(Type *a,int n); /构造函数,以数组a的值建立堆 MaxHeap()delete heapArr; /析构函数 int Insert(Type &d); /在堆中插入元素d Type DeleteTop(); /删除堆顶元素 Type GetTop()const /取得堆顶元素 return heapArr0; int IsEmpty() /判断堆是否为空 return heapCurrentSize=0; int IsFull() const /判断堆是否为满 return heapCurre

22、ntSize=heapMaxSize; void SetEmpty()heapCurrentSize=0;/置堆为空 void HeapSort(); /堆排序 void Show(int k) for(int i=0;ik;i+) coutheapArri.GetKey() ; private: int heapMaxSize; /堆中数据元素的最大数目 Type *heapArr; /存放堆中数据元素的数组 int heapCurrentSize; /堆中当前元素数目 void FilterDown(int p); /向下调整使以结点p为根的子树成为堆 void FilterUp(int

23、p); / 向上调整使以结点p为根的子树成为堆;templateint MaxHeap:Insert(Type &d) if(IsFull() cout堆已满endl;return 0; heapArrheapCurrentSize=&d; /在堆尾插入数据元素d FilterUp(heapCurrentSize); /向上调整为堆 heapCurrentSize+; return 1;templateMaxHeap:MaxHeap(int maxSize) /根据maxSize,建立空堆 if(maxSize=0) cerr堆的大小不能小于1endl; exit(1); heapMaxSiz

24、e=maxSize; heapArr=new TypeheapMaxSize; / 建立堆空间 heapCurrentSize=0;templateMaxHeap:MaxHeap(Type *a,int n) /根据数组a中的数据,建立堆,n为数组的大小 if(n=0) cerr堆的大小不能小于1endl; exit(1); heapMaxSize=n; /确定堆的最大空间 heapArr=new TypeheapMaxSize; /创建堆空间 /heapArr=a; /?直接赋值? for(int i=0;i=0) FilterDown(i); /从开始到heapCurrentSize-1为

25、止进行调整 i-; */templatevoid MaxHeap:FilterDown(const int start) /向下调整从start开始到heapCurrentSize-1为止的子序列成为最大堆 int i=start,j; Type temp=heapArri; if(heapCurrentSize=2) if(i=0&heapCurrentSize=2&heapArr0.GetKey()heapArr1.GetKey() heapArr0=heapArr1;heapArr1=temp; else j=2*i+1; /j为i的左孩子 while(jheapCurrentSize) if(jheapCurrentSize-1&heapArrj.GetKey()=heapArrj.G

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1