// 模拟list
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
//#define node<T> list_node<T>*;
#define ptr_node list_node<T>*
template<typename T> struct list_node
{
T data;
ptr_node pre;
ptr_node suc;
list_node(){} // 针对head和tail构造,根据语义,这两个不需要赋data值
list_node(T e,ptr_node p=NULL,ptr_node s=NULL):data(e),pre(p),suc(s){}
//ptr_node insert_as_pre(ptr_node p); // 是插数据,大哥!
ptr_node insert_as_pre(T const& e); // 返回该元素的插入处的节点指针
ptr_node insert_as_suc(T const& e);
};
template<typename T> ptr_node list_node<T>::insert_as_pre(T const& e) //以下两个返回被插入的位置
{
ptr_node temp = new list_node<T>(e);
this->pre->suc = temp;
temp->suc = this;
temp->pre = this->pre;
this->pre = temp;
return temp;
}
template<typename T> ptr_node list_node<T>::insert_as_suc(T const& e)
{
ptr_node temp = new list_node<T>(e);
// 链表的后插与前插是不一样的
temp->suc = this->suc;
temp->pre = this;
this->suc->pre = temp;
this->suc = temp;
return temp;
}
/**************************************************************************************/
template<typename T>
struct Func_visit
{
int add_num;
Func_visit(int n):add_num(n){}
void operator()(T& e) //这里用引用,否则局部变量又会销毁!!!
{
e += add_num;
}
};
template<typename T> class list
{
private:
int size; ptr_node head; ptr_node tail;
public:
list() { init(); } // 无参构造后size,head,tail默认=0
// 拷贝构造函数,对列表的整体复制 list(list<T> const& L) ERROR?yes!不要总想着拷贝构造函数的const&
list(list<T>& L) // cause:此错误可能是由于调用对象上的非 const 成员函数导致的 const 异常
{
//copy_nodes(head->suc, size); //想扇死你,完全没有理解拷贝的含义
copy_nodes(L.first(), L.size);
}
~list() // 包括头节点和尾节点全部删除
{
cout << "destructor" << endl;
clear();
delete head;
delete tail;
}
void init();
void copy_nodes(ptr_node pos, int n); // 从pos开始(包括pos),复制n个结点
ptr_node first(); // getfirst() 看着不舒服,仍然是返回指针类型(即位置)为后续函数调用
ptr_node last();
// 注意:这里的插入有两个位置
ptr_node insert(T const& e,ptr_node pos); //e作为pos的前驱插入
ptr_node insert(ptr_node pos, T const& e); // 作为后继插入
ptr_node insert_as_first(T const& e); // 便于阅读,后面就不会错
ptr_node insert_as_last(T const& e);
ptr_node find(T const& e, int n, ptr_node pos); // 从当前位置往前查找n个元素
int dedupilate(); // 唯一化
int Size();
void reverse();
T operator[](int r)const; //ptr_node operator[](int r); // 脑子再次短路,重载下标运算符当然是返回元素的值了
T remove(ptr_node pos); // 删除p处的节点,返回元素的值
//ptr_node select_max(list const& List); 本来就在里面,传你妈的傻逼参数
ptr_node search(T const& e, int n, ptr_node pos)const;
ptr_node select_max(ptr_node pos,int n); // n表示n个元素
void selection_sort(ptr_node pos, int n); // 从pos开始的连续n个节点,即一共n个元素
void insertion_sort(ptr_node p, int n);
int uniquify(); // 有序列表唯一化
//void traverse(void(visit*)(T&));
void traverse1(void(*visit)(T&));
template<typename VST> void traverse2(VST& func_visit);
void show_list();
int clear(); // 返回清除元素的个数
};
template<typename T>void list<T>::init()
{
head = new list_node<T>;
tail = new list_node<T>;
head->pre = NULL; head->suc = tail;
tail->pre = head; tail->suc = NULL;
size = 0;
}
template<typename T> void list<T>::copy_nodes(ptr_node pos, int n)
{
init(); // 这里就相当于对要拷贝的列表赋值了,head和tail节点都给出了,接下来只需拷贝即可
while (n--)
{
insert_as_last(pos->data);
pos = pos->suc;
}
}
template<typename T> ptr_node list<T>::first()
{
return head->suc;
}
template<typename T> ptr_node list<T>::last()
{
return tail->pre;
}
template<typename T>ptr_node list<T>::insert_as_first(T const& e)
{
return insert(e, first());
}
template<typename T>ptr_node list<T>::insert_as_last(T const& e)
{
return insert(last(), e);
}
template<typename T>ptr_node list<T>::insert(T const& e, ptr_node pos)
{
size++;
return pos->insert_as_pre(e);
}
template<typename T>ptr_node list<T>::insert(ptr_node pos, T const& e)
{
size++;
return pos->insert_as_suc(e);
}
template<typename T> ptr_node list<T>::find(T const& e, int n, ptr_node pos)
{
while (n--)
{
if ((pos = pos->pre)->data == e)
return pos;
}
return NULL;
}
template<typename T> int list<T>::dedupilate()
{
int old_size = size;
int steps = 1;
//for (ptr_node behind = first(), front = first()->suc; front != tail; front = front->suc) // 快慢指针
// 上面这样写就gg了,front就不是指针类型了
ptr_node behind;
ptr_node front;
for (behind = first(), front = first()->suc; front != tail; front = front->suc)
{
ptr_node pos = find(front->data, steps, front);
if (pos != NULL) // 在pos的地方找到了
remove(pos);
else
steps++;
}
return old_size - size;
}
template<typename T> T list<T>::operator[](int r)const
{
// 关于这个数数问题,自己比划比划
ptr_node ptr = head->suc;
while (r-- > 0)
ptr = ptr->suc;
return ptr->data;
}
template<typename T> int list<T>::Size() // 别与size重名了('~')
{
return size;
}
template<typename T> void list<T>::reverse()
{
ptr_node front = first();
ptr_node behind = last();
//while (front != behind || front->suc != behind) // 这就说明你的逻辑有问题
while(front!=behind && front->suc!=behind)
{
// 交换两个指针的数据
T temp = front->data;
front->data = behind->data;
behind->data = temp;
front = front->suc;
behind = behind->pre;
}
}
template<typename T> T list<T>::remove(ptr_node pos) // 假定可以删除
{
T temp = pos->data;
pos->pre->suc = pos->suc;
pos->suc->pre = pos->pre;
size--;
delete pos;
return temp;
}
template<typename T>void list<T>::show_list()
{
ptr_node ptr = head->suc;
int length = size;
while (length-- > 0) // --length就完犊子了,少了一个
{
cout << ptr->data << " ";
ptr = ptr->suc;
}
cout << endl;
}
template<typename T>ptr_node list<T>::search(T const& e, int n, ptr_node pos)const
{
// 返回不超过e的最靠右元素
ptr_node ptr = pos->pre;
for (int i = 0; i<n && ptr->data>e;i++,ptr=ptr->pre)
{
}
return ptr;
// 插入的时候要在ptr后面插
}
template<typename T>ptr_node list<T>::select_max(ptr_node pos,int n)
{
// 要保证语义,从pos开始,(包括pos)一共n个节点
ptr_node temp = pos;
for (int i = 1; i < n; ++i)
{
temp = temp->suc;
}
ptr_node ptr = temp; // 从后往前扫描
// 每个节点都要遍历,共n次
while (n>0)
{
if (ptr->data > temp->data)
{
temp = ptr;
}
ptr = ptr->pre;
n--;
}
//cout << "max=" << temp->data;
return temp;
}
template<typename T>void list<T>::selection_sort(ptr_node pos, int n)
{
ptr_node ptr = tail;
while (n>0)
{
ptr_node max_item = select_max(first(),n);
//cout <<"max="<< max_item->data;
ptr->insert_as_pre(max_item->data);
remove(max_item);
ptr = ptr->pre;
n--;
// 这一步很重要,注意接口之间的关系
size++;
}
}
template<typename T>void list<T>::insertion_sort(ptr_node p, int n)
{
// n-1次
for (int r=0;r<n;++r)
{
//ptr位置,不包括ptr,往前数r个元素
insert(search(p->data,r,p),p->data); // 插的语义很重要!!!事先规定好,否则浪费时间
p = p->suc;
remove(p->pre);
//size++;
}
}
template<typename T> int list<T>::uniquify()
{
if (size < 2)
return 0;
int old_size = size;
ptr_node behind = first();
ptr_node front = behind->suc;
while (front != tail)
{
if (behind->data == front->data) {
behind = behind->suc;
remove(behind->pre);
}
behind = front;
front = front->suc;
}
return old_size - size;
}
template<typename T> void visit(T& e)
{
e += 3;
}
//template<typename T> void list<T>::traverse(visit)// 怎么还没有理解,参数是函数指针照样写,只是传参数的时候用visit罢了
template<typename T> void list<T>::traverse1(void(*visit)(T&))
{
for (ptr_node ptr = first(); ptr != tail; ptr = ptr->suc)
visit(ptr->data);
}
template<typename T> template<typename VST>
void list<T>::traverse2(VST& func_visit)
{
for (ptr_node ptr = first(); ptr != tail; ptr = ptr->suc)
func_visit(ptr->data);
}
template<typename T>int list<T>::clear()
{
//int cnt = 0; // 我感觉自己的脑子有点问题
int old_size = size;
while (size>0) // 这里又出问题了,remove接口已经将size--了,你怕是在梦游
{
//ptr_node ptr = head->suc;
ptr_node ptr = tail->pre;
remove(ptr);
}
return old_size;
}
int main()
{
list<int> list1;
// insert(i,first) first只能往前插,同理insert(last,i) last只能往后插
for (int i = 0; i < 6; ++i)
{
//my_list.insert(i,my_list.first());
list1.insert(list1.last(),i+3);
}
list1.insert(list1.first(), 7);
list1.insert(list1.first(), 5);
list1.insert(list1.last(), 5);
cout << "list1:";
list1.show_list();
/*list1.dedupilate();*/
/*for (int i = 0; i < list1.Size(); ++i)
{
cout << "my_list[" << i << "]=" << list1[i] << endl;
}*/
cout << "list2:";
list<int> list2(list1);
list2.show_list();
cout << "list2.sort:";
//list2.selection_sort(list2.first(),list2.Size());
list2.insertion_sort(list2.first(), list2.Size());
list2.show_list();
cout << "list2.reverse:";
list2.reverse();
list2.show_list();
//list2.traverse(visit);
//list2.traverse2(Func_visit<int>(5));
// 你又忘了呀!!!
/*Func_visit<int>func_add(50);
list2.traverse2(func_add);
cout << "list2.traverse:";*/
cout << "list2.uniquify:";
list2.uniquify();
list2.show_list();
list2.clear();
cout << "list2.size="<<list2.Size() << endl;
}
10-02
1734
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交