一
单链表
1. 结点声明:
template <class T>
struct Node
{
T data;
Node<T> *next; //此处<T>也可以省略
}
2. 类声明:
template <class T>
class LinkList
{
public:
LinkList( ){first=new Node<T>; first->next=NULL;} //建立只有头结点的空链表
LinkList(T a[ ], int n); //建立有n个元素的单链表
~LinkList( ); //析构函数
int Length( ); //求单链表的长度
T Get(int i); //取单链表中第i个结点的元素值
int Locate(T x); //求单链表中值为x的元素序号
void Insert(int i, T x); //在单链表中第i个位置插入元素值为x的结点
T Delete(int i); //在单链表中删除第i个结点
void PrintList( ); //遍历单链表,按序号依次输出各元素
private:
Node<T> *first; //单链表的头指针
};
3. 头插法建立单链表
template <class T>
LinkList<T>::LinkList(T a[], int n)
{
first = new Node<T>;
first->next = NULL; //初始化一个空链表
for(int i = 0; i < n; i ++)
{
Node<T> *s = new Node<T>;
s->data = a[i]; //为每个数组元素建立一个结点
s->next = first->next; //插入到头结点之后
first->next = s;
}
}
4. 尾插法建立单链表
template <class T>
LinkList<T>::LinkList(T a[], int n) {
first = new Node<T>;//生成头结点
Node<T> *r = first; //尾指针初始化
for (int i = 0; i< n; i++)
{
Node<T> *s = new Node<T>;
s->data = a[i]; //为每个数组元素建立一个结点
r->next = s; //插入到终端结点之后
r = s;
}
r->next = NULL; //单链表建立完毕,将终端结点的指针域置空
}
5. 析构函数
template <class T>
LinkList<T>::~LinkList()
{
Node<T> *p = first; //工作指针p初始化
while (p) //释放单链表的每一个结点的存储空间
{
Node<T> *q = p; //暂存被释放结点
p = p->next; //工作指针p指向被释放结点的下一个结点,使单链表不断开
delete q;
}
}
6. 插入算法
template <class T>
void LinkList<T>::Insert(int i , T x)//插入算法
{
Node<T> *p;
p = first; int j = 0; //工作指针p初始化
while (p && j < i-1)
{
p = p->next;//工作指针p后移
j++;
}
if(!p) throw "位置";
else
{
Node<T> *s;
s = new Node<T>; //向内存申请一个结点s,其数据域为x
s->data = x;
s->next = p->next;//将结点s插入到结点p之后
p->next = s;
}
}
7. 按位查找
template <class T>
T LinkList::Get(int i)
{
Node<T> *p;
p=first->next; int j=1; //或p=first; j=0;
while (p && j<i)
{
p=p->next; //工作指针p后移
j++;
}
if (!p) throw "位置";
else return p->data;
}
8. 删除算法
template <class T>
T LinkList::Delete(int i)
{
Node<T> *p = first; int j = 0; //工作指针p初始化
while (p && j<i-1) //查找第i-1个结点
{
p=p->next;
j++;
}
if (!p | | !p->next) throw "位置"; //结点p不存在或结点p的后继结点不存在
else {
q=p->next; x=q->data; //暂存被删结点
p->next=q->next; //摘链
delete q;
return x;
}
}
如何将链表倒置?
template <class T> void LinkList<T>::reverse() { Node<T> *p; /*临时存储*/ Node<T> *p1; /*存储返回结果*/ Node<T> *p2; /*源结果节点一个一个取*/ p1 = NULL; /*开始颠倒时,已颠倒的部分为空*/ p2 = first; /*p2指向链表的头节点*/ while (p2 != NULL) { p = p2->next; p2->next = p1; p1 = p2; p2 = p; } first = p1; } |
双链表
1、结点声名
template <class T>
struct Node
{
T data;
Node<T> *prior, *next;
};
2、在结点p后面插入一个新结点s
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
3、设指针p指向待删除结点,删除操作
p->prior->next = p->next;
p->next->prior = p->prior;
思考: 带头结点的双向循环链表L为空表的条件
(L==L->next)&&(L==L->prior)
思考:单链表的排序算法?
template <class T> void LinkList<T>::sort() { Node<T> *p; Node<T> *q; Node<T> *small; T temp; for (p=first->next; p->next != NULL; p = p->next) { small = p; for (q = p->next; q !=NULL; q=q->next) { if (q->data < small->data) small = q; } if (small != p) { temp = p->data; p->data = small->data; small->data = temp; } } } |
普通的双链表
#include <iostream>
#include <list>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
list<int> lst1;//lst1 ()
list<int> lst2(3,7); //lst2 (7 7 7)
for (int j = 1; j <= 5; j ++)
lst1.push_back(j);//lst1 (1 2 3 4 5)
list<int>::iterator i1 = lst1.begin(), i2 = i1, i3;
i2++; i2++;i2++;
list<int> lst3(++i1,i2);//lst3 (2 3)
list<int> lst4(lst1);
cout << "建立lst4:" << endl;//lst4 (1 2 3 4 5)
i1 = lst4.begin();
lst4.splice(++i1,lst2);//删除lst2的结点,插入到++i1所引用的位置之前
//lst4 (1 7 7 7 2 3 4 5) lst2 ()
lst2 = lst1;//lst1 (1 2 3 4 5)
i2 = lst2.begin();
lst4.splice(i1,lst2,++i2);//从lst2中删除迭代器++i2所引用的结点,插入到迭代器i1所引用的位置之前
//lst4 (1 7 7 7 2 2 3 4 5)
i2 = lst2.begin();
i3 = i2;
lst4.splice(i1,lst2,i2,++i3);//从lst2中删除迭代器i2和++i3所指范围的结点,插入到i1所引用位置之前
// lst 4 (1 7 7 7 2 1 2 3 4 5)
lst4.remove(1);//删除链表中包含1的全部结点
//lst4 (7 7 7 2 2 3 4 5)
lst4.sort();//增序排序
//lst4 (2 2 3 4 5 7 7 7)
lst4.unique();//删除重复元素
//lst4 (2 3 4 5 7)
lst1.merge(lst2);//从lst2中删除全部结点,将其已整理好的顺序插入到lst1中
//lst1 (1 2 3 3 4 4 5 5 )
lst3.reverse();//反转链表
//lst3 (3 2)
lst4.reverse();//反转链表
//lst4 (7 5 4 3 2)
lst3.merge(lst4,greater<int>());
//lst3 (7 5 4 3 3 2 2)
lst3.remove_if(bind2nd(not_equal_to<int>(),3));
//lst3 (3 3)
lst3.unique(not_equal_to<int>());
//lst3 (3 3)
//lst1 (1 2 3 3 4 4 5 5) lst2 () lst3 (3 3) lst4 ()
return 0;
}
双端队列
#include <iostream>
#include <algorithm>
#include <deque>
using namespace std;
int main()
{
deque<int> dq1;
dq1.push_front(1);//dq1 (1)
dq1.push_front(2);//dq1 (2 1)
dq1.push_back(3);//dq1 (2 1 3)
dq1.push_back(4);//dq1 (2 1 3 4)
deque<int> dq2(dq1.begin()+1,dq1.end()-1);//dq2 (1 3)
dq1[1] = 5;//dq1 (2 5 3 4)
dq1.erase(dq1.begin());//dq1 (5 3 4)
dq1.insert(dq1.end()-1,2,6);//dq1 (5 3 6 6 4)
sort(dq1.begin(),dq1.end());//dq1 (3 4 5 6 6)
deque<int> dq3;//dq3 ()//
dq3.resize(dq1.size()+dq2.size());//dq3 (0 0 0 0 0 0 0)
merge(dq1.begin(),dq1.end(),dq2.begin(),dq2.end(),dq3.begin());
return 0;
}