目录
单链表
双向链表
STL中的list
/*数据结构:单链表*/
#ifndef LIST_H
#define LIST_H
#include
using namespace std;
typedef int ElementType;//定义数据类型
class Node{//定义链表节点
public:
Node(){next=NULL;}
ElementType data;
Node* next;
};
class List{
public:
/*构造函数*/
List();
/*析构函数*/
~List();
/*修改链表的方法*/
void insert_head(ElementType data);//将data插入到链表头部
void insert_tail(ElementType data);//将data插入到链表尾部
bool insert_next(Node* node,ElementType data);//将data插入到node结点后
bool delete_next(Node* node);//删除node结点后的节点
void reverse();//逆置
/*检索链表的方法*/
Node* Search(ElementType data);//查找数据为data的结点
Node* Find(int ith);//返回列表中第ith个结点,其中头节点记为第0结点
/*获取链表基本信息的方法*/
int list_size(){return size;}
Node* head(){return pHead;}
Node* tail(){return pTail;}
/*其他*/
void display();//从头到尾输出链表
private:
size_t size;
Node* pHead;//头结点指针
Node* pTail;//指向链表尾部结点的指针
};
#endif // LIST_H
/*数据结构:单链表*/
#include "List.h"
/*****************************************************************
Function:List
Description:
构造函数,主要是初始化size、实例化头结点、初始化
头指针pHead和尾指针pTail。
*****************************************************************/
List::List(){
size = 0;
pHead = new Node();
pTail = pHead;
}
/*****************************************************************
Function:~List
Description:析构函数,主要是释放链表的空间。
*****************************************************************/
List::~List(){
//不断的删除头节点后面的节点,直至size=0
while(size>0)
delete_next(pHead);
delete pHead;
}
/*****************************************************************
Function:insert_head
Description:将数据data插入到链表的头部。
*****************************************************************/
void List::insert_head(ElementType data){
//申请空间存储data
Node* node = new Node();
node->data = data;
//当为空链表时,插入头部的同时还有移动尾部指针
if(size==0)
pTail = node;
node->next = pHead->next;
pHead->next = node;
size++;
}
/*****************************************************************
Function:insert_head
Description:将数据data插入到链表的尾部。
*****************************************************************/
void List::insert_tail(ElementType data){
Node* node = new Node();
node->data = data;
pTail->next = node;
pTail = pTail->next;
size++;
}
/*****************************************************************
Function:insert_next
Description:将数据data插入到结点node之后。
*****************************************************************/
bool List::insert_next(Node* node,ElementType data){
if(node==NULL)
return false;
Node* p = new Node();
p->data = data;
p->next = node->next;
node->next = p;
//当插入的节点为尾部时,需要移动尾部指针pTail
if(node==pTail)
pTail = p;
size++;
return true;
}
/*****************************************************************
Function:delete_next
Description:将结点node之后的节点删除。
*****************************************************************/
bool List::delete_next(Node* node){
if(NULL==node||NULL==node->next)
return false;
Node* p = node->next;
node->next = node->next->next;
delete p;
size--;
return true;
}
/*****************************************************************
Function:reverse
Description:反转链表。
*****************************************************************/
void List::reverse(){
if(size<2)
return;
//pre是p的前序结点,p是post的前序结点
Node* pre = pHead->next;
Node* p = pre->next;
Node* post = NULL;
//处理尾部结点
pTail = pre;
pTail->next = NULL;
while(p!=NULL){
post = p->next;
p->next = pre;
pre = p;
p = post;
}
//处理头结点
pHead->next = pre;
}
/*****************************************************************
Function:Search
Description:查找数据为data的节点。
*****************************************************************/
Node* List::Search(ElementType data){
if(size>0){
Node* p = pHead->next;
while(p!=NULL){
if(p->data==data)
return p;
p = p->next;
}
}
return NULL;
}
/*****************************************************************
Function:Find
Description:返回列表中第ith个节点,其中头节点记为第0节点。
*****************************************************************/
Node* List::Find(int ith){
if(ith<0||ith>size)
return NULL;
Node* p = pHead;
for(int i=0;inext;
return p;
}
void List::display(){
Node* p = pHead->next;
while(p!=NULL){
cout<data<<" ";
p = p->next;
}
cout<
#include
#include "List.h"
using namespace std;
int main()
{
List* list = new List();
list->insert_tail(4);
list->insert_head(3);
list->insert_head(2);
list->insert_head(1);
list->insert_next(list->tail(),5);//1,2,3,4,5
list->display();
list->delete_next(list->Search(3));//1,2,3,5
list->display();
list->reverse();//5,3,2,1
list->display();
delete list;//µ÷ÓÃÎö¹¹º¯Êý
return 0;
}
1.在头结点后插入(insert_head)
正常的插入操作
特殊情况:当列表为空时,除了普通的插入操作,还需要移动pTail.
2.在指定结点后插入(insert_next)
类似问题(1)如果插入的位置是pTail时,需要移动pTial。
3.反转链表(reverse)
需要三个指针pre、p、post,反转后p会指向pre,此时会丢掉原来p之后的结点,因此需要使用post进行记录。
/*数据结构:双向链表*/
#ifndef DLIST_H
#define DLIST_H
#include
using namespace std;
typedef int ElementType;
class DNode{
public:
DNode(){
prev = NULL;
next = NULL;
}
ElementType data;
DNode* prev;
DNode* next;
};
class DList{
public:
DList();
~DList();
/*插入、删除*/
void insert_next(DNode* node,ElementType data);//在结点node后插入数据data
void insert_prev(DNode* node,ElementType data);//在结点node前插入数据data
bool remove(DNode* node);//删除node结点
/*查找*/
DNode* Search(ElementType data);//查找链表中数据为data的结点
DNode* Find(int ith);//查找链表中第ith个结点
/*链表信息*/
int list_size(){return size;}
DNode* head(){return pHead;}
DNode* tail(){return pTail;}
/*其他*/
void display();
private:
size_t size;
DNode* pHead;
DNode* pTail;
};
#endif // DLIST
/*数据结构:双向链表*/
#include "DList.h"
/*****************************************************************
Function:DList
Description:
构造函数,主要是初始化size、实例化头结点、初始化
头指针pHead和尾指针pTail。
*****************************************************************/
DList::DList(){
size = 0;
pHead = new DNode();
pTail = pHead;
}
/*****************************************************************
Function:~DList
Description:析构函数,主要是释放链表的空间。
*****************************************************************/
DList::~DList(){
while(size>0)
remove(pTail);
delete pHead;
}
/*****************************************************************
Function:insert_next
Description:在node结点后插入数据data。
*****************************************************************/
void DList::insert_next(DNode* node,ElementType data){
if(NULL==node)
return;
DNode* p = new DNode();
p->data = data;
if(node->next!=NULL){//如果node不是末尾的结点
//处理p与node->next的关系
p->next = node->next;
node->next->prev = p;
}
//处理p与node的关系
node->next = p;
p->prev = node;
//如果node是pTail,那么就修改pTail
if(node==pTail)
pTail = node->next;
size++;
}
/*****************************************************************
Function:insert_prev
Description:将数据data插入到结点node之前。
*****************************************************************/
void DList::insert_prev(DNode* node,ElementType data){
//node为空或者在pHead前插入结点是不允许的
if(node==NULL||node==pHead)
return;
DNode* prev = node->prev;
this->insert_next(prev,data);
}
/*****************************************************************
Function:remove
Description:从链表中删除node结点。
*****************************************************************/
bool DList::remove(DNode* node){
if(NULL==node)
return false;
DNode* prev = node->prev;
if(node==pTail){
//如果node是末尾结点,直接修改前序结点,并且要修改pTail
prev->next = NULL;
pTail = prev;
}
else{
prev->next = node->next;
node->next->prev = prev;
}
delete node;
size--;
return true;
}
/*****************************************************************
Function:Search
Description:查找链表中数据为data的结点。
*****************************************************************/
DNode* DList::Search(ElementType data){
DNode* p = pHead->next;
while(p!=NULL){
if(p->data==data)
return p;
p = p->next;
}
}
/*****************************************************************
Function:Find
Description:查找链表中第ith个结点。
*****************************************************************/
DNode* DList::Find(int ith){
if(ith>size||ith<1)
return NULL;
DNode* p = pHead;
for(int i=0;inext;
return p;
}
void DList::display(){
DNode* p = pHead->next;
while(p!=NULL){
cout<data<<" ";
p = p->next;
}
cout<
/*数据结构:双向链表*/
#include
#include "DList.h"
using namespace std;
int main()
{
DList* l = new DList();
for(int i=0;i<3;i++)
l->insert_next(l->head(),3-i);
l->display();//1,2,3
l->insert_prev(l->tail(),4);
l->display();//1,2,4,3
l->remove(l->Search(4));
l->display();//1,2,3
delete l;
return 0;
}
1.插入方法
2.删除方法
3.不论是插入还是删除,要注意处理pTail这种特殊情况。
/*STL中的List*/
#include
#include
using namespace std;
int main(){
/*构造函数*/
list L0;//空list
list L1(9);//包含9个0的list
list L2(8,3);//包含8个3的list
list L3(L2);//复制L2到L3
list L4(L2.begin(),L2.end());//从L2.begin()到L2.end()复制到L4
/*重新分配值*/
L0.assign(4,1);//4个1
/*插入*/
L0.push_back(3);//链表尾插入
L0.push_front(2);//链表头插入
L0.insert(++L0.begin(),2,5);//在指定的位置插入2个5
/*获取元素*/
int& front = L0.front();//返回第一个元素的引用
int& back = L0.back();//返回最后一个元素的引用
list::iterator begin = L0.begin();//返回第一个元素的指针
list::iterator end = L0.end();//返回最后一个元素的指针
/*删除*/
L1.pop_back();//删除链表尾元素
L1.pop_front();//删除链表头元素
L1.erase(L1.begin());//删除某个元素
L1.erase(++L1.begin(),--L1.end());//删除指定区域的元素
L1.insert(L1.begin(),3,2);
L1.remove(2);//从L1中删除所有的2
L1.clear();//清除所有元素
/*交换两个链表*/
L0.swap(L1);
/*合并两个链表*/
L1.merge(L2);
/*排序*/
L1.sort(greater ());
/*反转*/
L1.reverse();
/*去除唯一值*/
L1.unique();
/*链表大小的操作*/
L1.size();//链表中元素的个数
L1.max_size();//链表的总容量
L1.empty();//判断链表是否为空
L1.resize(10,-1);//重塑长度为10,新的结点使用-1填充
L1.resize(3);//重塑长度为3,将后面的结点去掉
/*遍历*/
list::iterator iter;
iter = L1.begin();
while(iter!=L1.end()){
cout<<*iter++<<" ";
}
return 0;
}