再简单的数据结构都有实现的意义
线性表是最最基础的数据结构,因此我们需要高效地实现它,并用它为我们以后构建高效的数据结构提供帮助。
实现过程中的疑惑
有人建议笔者在表头处放置一个空的头结点,说是这样可以方便我们在最开始插入元素,但整个程序写下来,也没觉得方便了多少,因此下次准备不加试试。
类的封装性让我无法处理链表的归并。一开始,我的想法是类中的归并函数,接受一个List的对象,把两个对象归并,并把接受的对象的空间给销毁。但是,写起来的时候却发现,我并不能访问接受的对象的头指针,这样就没有办法进行归并了。
- 对链表进行排序,最优的算法就是归并排序了,时间上来说,O(nlogn)已经达到基于比较的排序算法的下限,空间上来说,这里又可以做到原地排序。但是, 即使我实现了并归,链表的拆分还是没能成功调试。。。。。。。
#include <iostream>
using namespace std;
template <typename Key>
struct Node
{
Key key;
Node* next;
};
template <typename Key>
class List
{
public:
List();
~List();
void Clear();
bool IsEmpty()const
{
return ElemSize == 0;
}
int Length()const
{
return ElemSize;
}
bool IsContain(const Key& rhs)const;
Key Get(int index)const;
void Put(const Key& rhs,int index ); //Insert Element at the index of x
Key Delete(int index); //Delete the element at the index of x
// List Merge(List ) ;//?????
// void Sort();
void Print()const;
void Reverse();
//iterator
private:
Node<Key>* head;
int ElemSize;
};
int main()
{
List<int> MyList;
int a;
MyList.Put(1,0);
MyList.Put(2,0);
MyList.Put(3,0);
MyList.Put(4,0);
MyList.Put(5,2);
MyList.Print();
cout<<"The length of MyList is :"<<MyList.Length()<<endl;
cout<<"Index 1 :"<<MyList.Get(1)<<endl;
MyList.Delete(1);
cout<<"after delete at the index of 1:";
MyList.Print();
if(MyList.IsContain(3))
cout<<"It contains 3"<<endl;
if(MyList.IsContain(5))
cout<<"It contains 5"<<endl;
if(MyList.IsEmpty())
cout<<"It's empty1"<<endl;
MyList.Clear();
if(MyList.IsEmpty())
cout<<"It's empty2"<<endl;
cin>>a;
return 0;
}
template <typename Key>
List<Key>::List()
{
head = new Node<Key>;
head->next = NULL;
ElemSize = 0;
}
template <typename Key>
List<Key>::~List()
{
Node<Key>* p = head;
head = head->next;
while(head!=NULL)
{
delete(p);
p = head;
head = head->next;
}
delete(p);
ElemSize = 0;
}
template <typename Key>
void List<Key>::Put(const Key& rhs,int index)
{
Node<Key>* p = head->next;
Node<Key>* pre = head;
Node<Key>* x = new Node<Key>;
x->key = rhs;
if(index>ElemSize||index<0)
throw "IndexError";
while(index-->0)
{
if(p!=NULL)
{
pre = p;
p = p->next;
}
}
x->next = pre->next;
pre->next = x;
ElemSize++;
}
template <typename Key>
void List<Key>::Print()const
{
Node<Key>* p = head->next;
while(p!=NULL)
{
cout<<p->key<<" ";
p = p->next;
}
if(ElemSize==0)
cout<<"NULL";
cout<<endl;
}
template <typename Key>
void List<Key>::Reverse()
{
Node<Key>* pre=NULL,*now=NULL,*next=NULL,*first=NULL;//Only change the node pointed by "now"
if(ElemSize<=1)
return ;
first = head;
pre = head->next;
now = pre->next;
next = now->next;
pre->next = NULL;
while(next!=NULL)
{
now->next = pre;
pre = now;
now = next;
next = next->next;
}
now->next = pre;
head->next = now;
}
template <typename Key>
void List<Key>::Clear()
{
Node<Key>* now = head->next->next;
Node<Key>* pre = head->next;
head->next = NULL;
while(now!=NULL)
{
delete(pre);
pre = now;
now = now->next;
}
delete(pre);
ElemSize = 0;
}
template <typename Key>
bool List<Key>::IsContain(const Key& rhs)const
{
Node<Key>* p = head->next;
while(p!=NULL&&p->key!=rhs)
p = p->next;
if(p==NULL)
return false;
else return true;
}
template <typename Key>
Key List<Key>::Get(int index)const
{
Node<Key>* p = head->next;
if(index>=ElemSize||index<0)
throw "IndexError";
while(index-->0&&p!=NULL)
p = p->next;
return p->key;
}
template <typename Key>
Key List<Key>::Delete(int index)
{
Node<Key>* p = head;
Key key ;
if(index>=ElemSize||index<0)
throw "IndexError";
while(index-->0&&p->next!=NULL)
{
p = p->next;
}
Node<Key>* ToDe = p->next;
p->next = p->next->next;
key = ToDe->key;
delete(ToDe);
ElemSize--;
return key;
}