//链表数据结构的模板类
#include <iostream>
#include <assert.h>
using namespace std;
#define N 10
template <class Type>
struct node
{
Type value;
node<Type> *next;
node<Type> *pre;
};
template <class Type>
class list_class
{
private:
node<Type> *head;
node<Type> *tail;
int len;
public:
list_class();
list_class(list_class<Type> &);
~list_class();
bool IsEmpty();//空返回1,不空返回0
void Insert(node<Type> &); //这里在头插入一个node元素,不是指针,所以需要在函数里再开辟空间
void Insert(node<Type> *);//这个是插入node元素指针的方法。不在函数里开辟空间,插入的时候需要自己开辟空间;
void Insert(const Type &);//对使用来说,应该插入等操作都是针对value的,,
node<Type> * Search(Type); //search方法根据关键字k查找这个元素,我觉得是针对有卫星数据的情况,没有卫星数据这个方法并没什么用,或者就是单纯给其他方法调用,先实现一下吧
//我这里就做成返回node指针的方法,暂时给其他方法调用,可能不对外用
bool Delete(const Type );//根据value的值删除对应的节点,删除成功返回true,反之false
Type Pop();
Type & operator[](int i);
void ShowAll();
//再来一个交换[i][j]value的方法
void Swap(int &, int &);
//利用这个交换的方法与重载大的[]来排个序,放在外面
int GetLen()
{
return len;
}
};
void FastSortList(list_class<int> & a,int left,int right);
void BucketSortN(int a[],int n)//第一种分桶的方法,分N个桶,用数算索引。然后每个桶用链表存,解决之前数放到一个桶的问题。
{//这种的问题
int max=a[0],min=a[0];
int i,j;
int index;
int tmp;
for(i=0;i<n;i++)
{
if(a[i]>max) max = a[i];
if(a[i]<min) min = a[i];
}
cout<<"min="<<min<<endl;
cout<<"max="<<max<<endl;
list_class<int> *p = new list_class<int>[n];
for(i=0;i<n;i++)
{
cout<<"a[i]="<<a[i]<<endl;
index = (a[i]-min)*n/(max-min);
if(index==n) index--;
cout<<"index="<<index<<endl;
p[index].Insert(a[i]);
}
for(i=0;i<n;i++){
cout<<"fast sort begin"<<endl;
FastSortList(p[i],0,p[i].GetLen()-1);
cout<<"fast sort end"<<endl;
p[i].ShowAll();
}
for(i=0;i<n;i++)
{
cout<<"i="<<i<<endl;
for(j=0;j<n;j++)
{
if(p[j].IsEmpty()) continue;
else
{
cout<<"j="<<j<<endl;
a[i] = p[j].Pop();
cout<<"j finished"<<endl;
break;
}
}
}
return;
}
void FastSortList(list_class<int> & a,int left,int right)
{
if(left >= right)
return;
int reference = a[right];
int index = left;
int i = 0;
for(i=left;i<right;i++)
{
if(a[i]<reference)
{
a.Swap(index,i);
index++;
}
}
a.Swap(index,right);
FastSortList(a,left,index-1);
FastSortList(a,index+1,right);
}
int main()
{
list_class<int> test;
test.Insert(4);
test.Insert(8);
test.Insert(9);
test.Insert(18);
test.Insert(10);
test.Insert(1);
test.Insert(19);
int n = test.GetLen();
cout<<"n="<<n<<endl;
FastSortList(test,0,n-1);
test.ShowAll();
cout<<"delete exit="<<test.Delete(9)<<endl;
cout<<"delete not exit="<<test.Delete(9)<<endl;
test.ShowAll();
cout<<"[]="<<test[2]<<endl;
int a[N] = {13,1,99,14,75,13,6,9,71,36};
BucketSortN(a,N);
for(int i=0;i<N;i++)
{
cout<<a[i]<<endl;
}
return 0;
}
template <class Type>
bool list_class<Type>::IsEmpty()
{
if(len==0) return true;
else return false;
}
template <class Type>
list_class<Type>::list_class()
{
head = new node<Type>;
tail = new node<Type>;
head->next = tail;
head->pre = NULL;
tail->pre = head;
tail->next = NULL;
len = 0;
cout<<"dafaule succsee"<<endl;
}
template <class Type>
list_class<Type>::list_class(list_class<Type> & arg)
{
len = arg.len;
head = new node<Type>;
head->pre = NULL;
tail = new node<Type>;
tail->next = NULL;
head->next = tail;
tail->pre = head;
node<Type> *tmp;
node<Type> *p;
//一开始想的是新建一个节点插到头后面,这样其实是比较麻烦的
/*
tmp = arg.head->next;
while(tmp!=arg.tail)
{
p = new node<Type>;
p->value = tmp->value;//处理新建的节点的内容与指针
p->next = head->next;
p->pre = head->next->pre;
head->next->pre = p;//断开头指针后面节点的指针
head->next = p;//头指针指到p;
tmp = tmp->next;
}
*/
//另外可以把头指针内容更新了以后,把头指针前移一个
tmp = arg.head->next;
while(tmp!=arg.tail)
{
p = new node<Type>;
head->value = tmp->value;//头指针的内容更新
p->next = head;//p指针指到现在的头指针
p->pre = NULL;//p指针是现在的头指针
head->pre = p;
head = p;//头指针现在指到了p;
}
}
template <class Type>
list_class<Type>::~list_class()
{
if(len==0)
{
delete head;
delete tail;
}
else
{
node<Type> *tmp;
/*
//这种从有内容的节点删完
tmp = head->next;
while(tmp!=tail)//每次指向head下一个节点,指到head下一个节点是尾
{
head->next = tmp->next;
tmp->next->pre = head;//把下一个节点的pre也指对了,其实没什么用
delete tmp;
tmp = head->next;
}
delete head;
delete tail;
*/
//另外一种还是从头节点开始处理
while(head->next!=NULL)
{
tmp = head;
head = head->next;
delete tmp;
}
delete head;
}
}
template <class Type>
void list_class<Type>::Insert(node<Type> & arg)//昨晚思考的结果觉得还是插入在前面比较方便处理,而不是在头与节点间插入这个节点
{
head->value = arg.value;
node<Type> *tmp;
tmp = new node<Type>;
tmp->next = head;
tmp->pre = NULL;
head->pre = tmp;
head = tmp;
return;
}
template <class Type>
void list_class<Type>::Insert(node<Type> * arg)
{
head->value = arg->value;
head->pre = arg;
arg->next = head;
arg->pre = NULL;
head = arg;
return;
}
template <class Type>
void list_class<Type>::Insert(const Type & value)
{
node<Type> *p = new node<Type>;
p->value = value;
cout<<"p->value="<<p->value<<endl;
Insert(p);
len++;
cout<<"insert finished"<<endl;
return;
}
template <class Type>
node<Type> * list_class<Type>::Search(Type value)
{
node<Type> *tmp;
tmp = head;
while(tmp->value!= value&&tmp->next!=NULL)
{
tmp = tmp->next;
}
if(tmp->next==NULL) return NULL;
else return tmp;
}
template <class Type>
bool list_class<Type>::Delete(const Type value)
{
node<Type> *tmp;
tmp = head->next;
while(tmp->value != value&&tmp->next!=NULL)
{
tmp = tmp->next;
}
if(tmp->next==NULL) return false;
else
{
len--;
tmp->pre->next = tmp->next;
tmp->next->pre = tmp->pre;
delete tmp;
return true;
}
}
template <class Type>
Type list_class<Type>::Pop()
{
assert(len>0);
node<Type> *tmp;
tmp = head->next;
Type out = tmp->value;
tmp->pre = NULL;
delete head;
head = tmp;
len--;
return out;
}
template <class Type>
Type & list_class<Type>::operator[](int i)
{
int count = -1;
node<Type> *tmp;
tmp = head->next;
while(tmp->next!=NULL)
{
count++;
if(count==i) break;
tmp = tmp->next;
}
assert(tmp->next!=NULL);
return tmp->value;
}
template <class Type>
void list_class<Type>::ShowAll()
{
if(len<=0) return;
node<Type> *tmp;
tmp = head->next;
cout<<"tmp= head->next"<<endl;
while(tmp->next!=NULL)
{
cout<<"value="<<tmp->value<<endl;
tmp = tmp->next;
}
return;
}
template <class Type>
void list_class<Type>::Swap(int & i, int & j)
{
Type tmp;
tmp = this->operator[](i);
this->operator[](i) = this->operator[](j);
this->operator[](j) = tmp;
}
回头看还有一些需要改进的地方,主要就是模板里面没有留卫星数据的位置。所以可以再加一个卫星数据的位置在node里面。