多关键字排序

很欢迎来看我的博客,我还有很多知识没有学习,这是我的考核作业!以此记录我的学习历程!大家参考就好!如有错误,敬请指出!在此,先谢谢一番!

多关键字排序就是基数排序,我是用单链表实现多关键字的排序的,但最主要的方法仍是“分配”,“收集”。单链表只是在分配与收集过程中起暂时的存储作用。不仅可以用链表,还可以用栈、队列……(都是线性的!!!(^_^))

这是结点类模板的定义:

#ifndef NODE_H

#define NODE_H

#define NULL 0

template<class ElemType>

struct Node

{

ElemType date;

Node<ElemType> *next;

Node();

Node(ElemType item,Node<ElemType> *link=NULL);

};

template<class ElemType>

Node<ElemType>::Node()

{

next=NULL;

}

template<class ElemType>

Node<ElemType>::Node(ElemType item,Node<ElemType> *link)

{

date=item;

next=link;

}

#endif // NODE_H

这是链表的代码:

#ifndef LINKLIST_H

#define LINKLIST_H

#include"Node.h"

#include<iostream>

using namespace std;

enum StatusCode{SUCCESS};

template<class ElemType>

class LinkList

{

public:

LinkList();

//这里没有定义析构函数,系统自己定义

int length() const;

bool Empty() const;

StatusCode Delete(int position,ElemType &e);

StatusCode Insert(int position, const ElemType &e);

void Traverse(void(*visit)(ElemType &));

protected:

Node<ElemType> *head;

mutable int curposition;

mutable Node<ElemType> *curPtr;

int count;

Node<ElemType>*GetElemPtr(int position) const;

void Init();

private:

};

//链表的初始化

template<class ElemType>

LinkList<ElemType>::LinkList()

{

Init();

}

template<class ElemType>

void LinkList<ElemType>::Init()

{

head=new Node<ElemType>;

curPtr=head;

curposition=0;

count=0;

}

template<class ElemType>

int LinkList<ElemType>::length() const

{

return count;

}

template<class ElemType>

bool LinkList<ElemType>::Empty() const

{

return count==0;

}

template<class ElemType>

Node<ElemType> *LinkList<ElemType>::GetElemPtr(int position) const

{

if(curposition>position)

{

curposition=0;

curPtr=head;

}

//即当curposition等于position的时候,返回

for(;curposition<position;curposition++)

{

curPtr=curPtr->next;

}

return curPtr;

}

template<class ElemType>

StatusCode LinkList<ElemType>::Delete(int position,ElemType &e)

{

Node<ElemType> *tmpPtr;

tmpPtr=GetElemPtr(position-1);

Node<ElemType> *nextPtr=tmpPtr->next;

tmpPtr->next=nextPtr->next;

e=nextPtr->date;

if(position==length())

{

curposition=0;

curPtr=head;

}else

{

curposition=position;

curPtr=tmpPtr->next;

}

count--;

delete nextPtr;

return SUCCESS;

}

template<class ElemType>

StatusCode LinkList<ElemType>::Insert(int position,const ElemType &e)

{

Node<ElemType> *tmpPtr;

tmpPtr=GetElemPtr(position-1);

Node<ElemType> *newPtr;

//即newPtr指向tmpPtr的下一个结点

newPtr=new Node<ElemType>(e,tmpPtr->next);

tmpPtr->next=newPtr;

curposition=position;

curPtr=newPtr;

count++;

return SUCCESS;

}

template<class ElemType>

void LinkList<ElemType>::Traverse(void(* visit)(ElemType&))

{

for(Node<ElemType> *tmpPtr=head->next;tmpPtr!=NULL;tmpPtr=tmpPtr->next)

{

(*visit)(tmpPtr->date);

}

}

template<class ElemType>

void print(ElemType e)

{

cout<<e<<endl;

}

#endif // LINKLIST_H

多关键字排序代码如下:

#include <iostream>

#include<math.h>

#include"LinkList.h"

using namespace std;

//分配

template<class ElemType>

void Distribute(ElemType elem[],int n,int r,int d,int i,LinkList<ElemType>list[])

{

for(int power=(int)pow((double)r,i-1),j=0;j<n;j++)

{

int index=(elem[j]/power)%r;

list[index].Insert(list[index].length()+1,elem[j]);

}

}

//收集

template<class ElemType>

void Colect(ElemType elem[],int n,int r,int d,int i,LinkList<ElemType>list[])

{

for(int k=0,j=0;j<r;j++)

{

ElemType tmpElem;

while(!list[j].Empty())

{

list[j].Delete(1,tmpElem);

elem[k++]=tmpElem;

}

}

}

template<class ElemType>

void RadixSort(ElemType elem[],int n,int r,int d)

{

LinkList<ElemType> *list;

list=new LinkList<ElemType>[r];

void (*visit)(int&);

visit=print;

for(int i=1;i<=d;i++)

{

Distribute(elem,n,r,d,i,list);

Colect(elem,n,r,d,i,list);

}

delete []list;

}

int main()

{

int a[]={98,67,42,21,18,16,54,32,64,56};

RadixSort(a,10,10,2);

cout << "Hello world!" << endl;

for(int i=0;i<10;i++)

{

if(i==9)

{

cout<<a[i]<<endl;

}

else

{

cout<<a[i]<<",";

}

}

return 0;

}

感悟:

其实我做出上面这个较为成功的代码,是经历了很多的艰辛的(累啊),但是当一个又一个问题被一一解决的成就感(快感,哈哈,又可以去吹了),这是那点艰辛无法比拟的!

所以在遇到困难与挫折的时候,

千万千万千万

要坚持

啊啊啊!!!

最后,在这里开始我的总结!

关于多关键字排序我犯了一个很小很小的错误(但是这个小东西让我找了好久好久,卧槽!),所以,一定要重视小细节!!!

言归正传,说一下问题:

1、关于sigsegv的问题,经过我查找众多资料后的理解:一般是指针的问题,就是引用了无效的内存!

偷偷地告诉你们:其实只是花括号的位置放错了(啊啊啊)!

2、还有一个问题,看下面代码:

NewPtr->date=e;

NewPtr->next=tmpPtr->next;

这导致的结果就是链表用的结点是同一个(啊啊啊)!

PS:我找了好久啊!!!

最后,我用下面这段代码:

NewPtr=new Node<ElemType>(e,tmpPtr->next)

每次都创建新的结点,就OK了(^_^)

很感谢大家耐心看完这么长的代码,辛苦了!希望一路走来,你可以跟我一样,坚持下来!加油!

时间: 2024-08-03 14:37:06

多关键字排序的相关文章

【基础练习】结构体定义比较函数双关键字排序

题目好长显得很高大上的样子其实一点也不是这样= = 再次感谢里奥同学的友情支持,没有他我现在还在一片云里雾里. 之前看ruka上一直说:可以自定义排序,但必须自定义小于号或者是比较函数,一直苦于如何实践,今天请教了里奥同学,终于拨云见日. 这样的题有很多类似的,像是codevs 3991排序(例题代码即为此题,但我会告诉你我是用后面那个题代码改的么···)  洛谷P1104 生日 都是很简单的多关键字排序 二话不说,上代码 //operator < and sort #include<cstd

常见的五类排序算法图解和实现(多关键字排序:基数排序以及各个排序算法的总结)

基数排序思想 完全不同于以前的排序算法,可以说,基数排序也叫做多关键字排序,基数排序是一种借助“多关键字排序”的思想来实现“单关键字排序”的内部排序算法. 两种方式: 1.最高位优先,先按照最高位排成若干子序列,再对子序列按照次高位排序 2.最低位优先:不必分子序列,每次排序全体元素都参与,不比较,而是通过分配+收集的方式. 多关键字排序 例:将下表所示的学生成绩单按数学成绩的等级由高到低排序,数学成绩相同的学生再按英语成绩的高低等级排序.        第一个关键字是数学成绩,第二个关键字是英

排序技巧——双关键字排序

一个萌新的成长之路 Background 在做题过程中,我们常会遇到对双关键字排序的情况,如:当分数相等时,序号小的在前. 这时我们可以通过定义cmp函数作为sort的参数进行排序. Solution 定义一个结构体,包含我们所需的关键字.例如,这是一个包含分数,序号和姓名的结构体. struct node{ int id,score; string name; }; -实现cmp函数,这里使用了两组不同的关键字. bool cmp_score_id(node a,node b) { if(a.

多关键字排序实验

一.实习目的 了解多关键字的使用范围:编写程序实现对汽车牌照的排序. 二.实验原理 了解多关键字的使用范围,并实现对牌照按多关键字排序后的快速查找. [问题描述] 为加快速度需先对数据记录按关键字排序,在汽车数据模型中,汽车是关键字,而且是具有结构特点的一类关键字.因为汽车牌照是汉字,字母和数字混编的,例如:AD7328.这种记录集合是一个适于利用多关键字进行排序的典型例子. [基本任务] (1)利用链式基数排序方法实现排序. (2)在排序的基础上,利用二分查找的思想,实现对汽车记录按关键字的查

Python关键字排序

一.当排序关键字多于1个时,我们使用lambda表达式来描述关键字key arr=[(1,4,3),(1,3,3),(2,1,4),(3,5,1)] arr.sort(key=lambda s:(s[0],s[1])) #两个关键字排序print(arr) # 可以看到输出结果是根据列表中元组的第一项和第二项排序[(1, 3, 3), (1, 4, 3), (2, 1, 4), (3, 5, 1)] 二.若我想让第一个关键字正序,第二个关键字倒序,该怎么办呢?arr=[(1,4,3),(1,3,

SQL 按关键字排序

SQL ORDER BY Keyword(按关键字排序) ORDER BY 关键字用于对结果集进行排序. SQL ORDER BY 关键字 ORDER BY 关键字用于按升序或降序对结果集进行排序. ORDER BY 关键字默认情况下按升序排序记录. 如果需要按降序对记录进行排序,可以使用DESC关键字. SQL ORDER BY 语法 SELECT column1, column2, ... FROM table_name ORDER BY column1, column2, ... ASC|

基本排序(四):索引指针排序、链表排序、关键字排序

1. 索引和指针排序 因为元素的数量或者数据量巨大等原因,我们不希望频繁移动要排序的元素.因此,不移动元素的排序方法是维持一个索引数组或者索引指针,而排序的目标就是重排索引数组或指针. 如: 初始化for(int i = 0; i < N; i++) a[i] = &data[i]; 使用间接比较#define less(A, B) (*A < *B) 使用下标或指针排序的主要原因是避免扰乱要排序的数据.我们可以对只读文件进行排序,或者针对一个文件的多个关键字进行排序. 另一个原因是避

c++结构体双关键字排序

1 #include<bits/stdc++.h> 2 using namespace std; 3 struct node{ 4 int l,r; 5 }num[100010]; 6 int w_comp(const node &a,const node &b){ 7 if (a.l!=b.l) return a.l>b.l;//先比较第一个关键字,从大到小排序 8 return a.r<b.r;//比较第二个关键字,从小到大排序 9 } 10 int main(

多关键字排序(里面有关于操作符(&lt;&lt;运算符 和 &gt;&gt;运算符 )的重载)

一种排序 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复:还知道这个长方形的宽和长,编号.长.宽都是整数:现在要求按照一下方式排序(默认排序规则都是从小到大):1.按照编号从小到大排序2.对于编号相等的长方形,按照长方形的长排序:3.如果编号和长都相同,按照长方形的宽排序:4.如果编号.长.宽都相同,就只保留一个长方形用于排序,删除多余的长方形:最后排好序按照指定格式显示所有的长方形: 输入 第一行有一个整数