#include <cstdio>
#include <cstdlib>
#ifndef LIST_H
#define LIST_H
struct Node;
struct List;
typedef Node* position;
typedef bool (*_cmpFunctor)(position _x,position _y);
typedef bool (*_predFunctor)(position _x);
struct Node {
int val;
position prev,succ;
Node() {}
Node(int _val,position _prev=NULL,position _succ=NULL) {
val=_val;
prev=_prev;
succ=_succ;
}
};
bool _greater(position _x,position _y) {
return _x->val<_y->val;
}
bool _less(position _x,position _y) {
return _x->val>_y->val;
}
bool _isdigit(position _x) {
return '0'<=_x->val&&_x->val<='9';
}
bool _isalpha(position _x) {
return 'a'<=_x->val&&_x->val<='z'||'A'<=_x->val&&_x->val<='Z';
}
_cmpFunctor greater=&_greater,less=&_less;
_predFunctor isalpha=&_isalpha,isdigit=&_isdigit;
struct List {
position _head,_tail;
//default constructor O(1)
List() {
_head=(position)malloc(sizeof(Node));
_tail=(position)malloc(sizeof(Node));
_head->succ=_tail;
_tail->prev=_head;
_head->prev=_tail->succ=NULL;
_head->val=_tail->val=0;
};
//int array constructor O(n)
List(int *_arr,int _len) {
_head=(position)malloc(sizeof(Node));
_tail=(position)malloc(sizeof(Node));
_head->succ=_tail;
_tail->prev=_head;
_head->prev=_tail->succ=NULL;
_head->val=_tail->val=0;
while(--_len!=-1)insert(0,_arr[_len]);
}
List(long long *_arr,int _len) {
_head=(position)malloc(sizeof(Node));
_tail=(position)malloc(sizeof(Node));
_head->succ=_tail;
_tail->prev=_head;
_head->prev=_tail->succ=NULL;
_head->val=_tail->val=0;
while(--_len!=-1)insert(0,_arr[_len]);
}
//string constructor O(n)
List(char *_str) {
_head=(position)malloc(sizeof(Node));
_tail=(position)malloc(sizeof(Node));
_head->succ=_tail;
_tail->prev=_head;
_head->prev=_tail->succ=NULL;
_head->val=_tail->val=0;
//int _len=sizeof(_str)/sizeof(char);
while(*_str)insert(_tail,*_str++);
}
//return the position of fist element O(1)
inline position begin() {
return _head->succ;
}
//return the end of list O(1)
inline position end() {
return _tail;
}
//return the size of list O(1)
inline int size() {
return _head->val;
}
//return the length of list O(1)
inline int length() {
return _head->val;
}
//push back the element O(1)
void push_back(Node _x) {
insert(_tail,_x.val);
}
//push back the element O(1)
void push_back(position _x) {
insert(_tail,_x->val);
}
//push front the element O(1)
void push_front(Node _x) {
insert(begin(),_x.val);
}
//push front the element O(1)
void push_front(position _x) {
insert(begin(),_x->val);
}
//return the position if find the val O(n)
position find(int _val,position _L=NULL,position _R=NULL) {
if(_L==NULL)_L=begin();
if(_R==NULL)_R=_tail;
position _toFind=_L;
while(_toFind!=_R) {
if(_toFind->val==_val)return _toFind;
_toFind=_toFind->succ;
}
return _toFind;
}
//return the last position that _val == val O(n)
position lower_bound(int _val,position _L=NULL,position _R=NULL) {
if(_L==NULL)_L=begin();
if(_R==NULL)_R=_tail;
position _toFind=_L;
while(_toFind!=_R) {
if(_toFind->val>_val)return _toFind->prev;
_toFind=_toFind->succ;
}
return _toFind;
}
//return the first position that _val > val O(n)
position upper_bound(int _val,position _L=NULL,position _R=NULL) {
if(_L==NULL)_L=begin();
if(_R==NULL)_R=_tail;
position _toFind=_L;
while(_toFind!=_R) {
if(_toFind->val>_val)return _toFind;
_toFind=_toFind->succ;
}
return _toFind;
}
//return the kth position O(n)
position search_kth(int _k,position _L=NULL,position _R=NULL) {
if(_L==NULL)_L=_head,_k++;
if(_R==NULL)_R=_tail;
position _toFind=_L;
while(_toFind!=_R&&_k--) {
_toFind=_toFind->succ;
}
return _toFind;
}
//insert new Node with val _val into the position _pos O(1)
void insert(position _pos,int _val) {
position _prevPos=_pos->prev,_newPos=(position)malloc(sizeof(Node));
_newPos->val=_val;
_newPos->succ=_prevPos->succ;
_prevPos->succ=_newPos;
_pos->prev=_newPos;
_newPos->prev=_prevPos;
_head->val++;
}
//insert new Node with val _val into the kth position O(n)
void insert(int k,int _val) {
insert(search_kth(k),_val);
}
//erase the node in the position _pos O(1)
void erase(position _pos) {
position _prevPos=_pos->prev;
_prevPos->succ=_pos->succ;
_prevPos->succ->prev=_prevPos;
free(_pos);
_head->val--;
}
//erase the node in the kth position O(n)
void erase(int k) {
erase(search_kth(k));
}
//clear the list O(n)
void clear() {
while(begin()!=end())erase(begin());
}
//crash the list and then you can't use it. O(n)
void crash() {
while(begin()!=end())erase(begin());
free(_head);
free(_tail);
}
//merge in the same order of _Llist and _Rlist O(length[Llist]+length[Rlist])
void merge(List _Llist,List _Rlist,_cmpFunctor _cmp = greater) {
position _L=_Llist.begin(),_R=_Rlist.begin();
while(_L!=_Llist.end()&&_R!=_Rlist.end()) {
if(_cmp(_L,_R)) {
push_back(_L);
_L=_L->succ;
} else {
push_back(_R);
_R=_R->succ;
}
}
while(_L!=_Llist.end()) {
push_back(_L);
_L=_L->succ;
}
while(_R!=_Rlist.end()) {
push_back(_R);
_R=_R->succ;
}
}
// split if P(_node.val) is true O(length[Llist]+length[Rlist])
void split(List &_Llist,List &_Rlist,_predFunctor _pred) {
position _itr=begin();
while(_itr!=end()) {
if(_pred(_itr))_Llist.push_back(_itr);
else _Rlist.push_back(_itr);
_itr=_itr->succ;
}
}
//A uni B O(length[A]+length[B])
void uni(List _A,List _B) {
List tem;
tem.merge(_A,_B);
position _itr=tem.begin()->succ,_temPos;
while(_itr!=tem.end()) {
_temPos=_itr;
_itr=_itr->succ;
if(_temPos->val==_temPos->prev->val)tem.erase(_temPos);
}
_head=tem._head;
_tail=tem._tail;
}
//A - B O(length[A]+length[B])
void dif(List _A,List _B) {
List tem;
tem.uni(_A,_B);
position _itr=tem.begin(),_Bitr=_B.begin(),_temPos;
while(_Bitr!=_B.end()&&_itr!=tem.end()) {
if(_Bitr->val==_Bitr->succ->val) {
_Bitr=_Bitr->succ;
continue;
}
if(_itr->val==_Bitr->val) {
_temPos=_itr;
_itr=_itr->succ;
tem.erase(_temPos);
_Bitr=_Bitr->succ;
} else _itr=_itr->succ;
}
_head=tem._head;
_tail=tem._tail;
}
//return the intersection of A and B O(length[A]+length[B])
void intersect(List _A,List _B) {
dif(_A,_B);
dif(_A,*this);
}
//partition of sort O(n)
position _partion(position _L,position _R,_cmpFunctor _cmp = greater) {
int _temVal;
Node _LNode=*_L;
position _pivot=_L,_ptr=_L->succ;
while(_ptr!=_R) {
if(_cmp(_ptr,&_LNode)) {
_pivot=_pivot->succ;
_temVal=_pivot->val;
_pivot->val=_ptr->val;
_ptr->val=_temVal;
}
_ptr=_ptr->succ;
}
_temVal=_pivot->val;
_pivot->val=_L->val;
_L->val=_temVal;
return _pivot;
}
//sort function: let the list [_L,_R) be in the order of _cmp O(nlogn)
void sort(position _L=NULL,position _R=NULL,_cmpFunctor _cmp = greater) {
if(_L==NULL)_L=begin();
if(_R==NULL)_R=end();
if(_L!=_R) {
position _pivot = _partion(_L,_R,_cmp);
sort(_L,_pivot,_cmp);
sort(_pivot->succ,_R,_cmp);
}
}
void prt_Str() {
position itr=begin();
while(itr!=end()) {
printf("%c ",itr->val);
itr=itr->succ;
}
puts("");
}
void prt_Arr() {
position itr=begin();
while(itr!=end()) {
printf("%d ",itr->val);
itr=itr->succ;
}
puts("");
}
};
#endif
[练习]自己写的c++链表模板 ver 1.5
最新推荐文章于 2024-08-14 21:15:33 发布