块状链表之代码剖析
来源:互联网 发布:免费抽奖软件 编辑:程序博客网 时间:2024/06/03 12:58
对块状链表不熟悉的请移步
块状链表解析
1.链表节点(block):
block加入模板
template<class ElemType>
构造函数
block<ElemType>(block<ElemType>* to,block<ElemType>* p):next(to),pre(p)
①:属性
ElemType data[MAXN]; int len ;/*本block有效数据的长度*/ bool rev ; block<ElemType> *next , *pre ;
并添加基本操作:分割,合并,删除下一个块
②:分割
在本块的指定位置处分割
void split(int pos)/*分裂,在pos处,分裂成->[0,pos)->[pos,len)->*/ { if( pos >= len || pos <= 0 ) return ;/*非法位置*/ if( this->rev )/*在某例中可能出现的反转情况*/ { reverse(this->data,this->data+this->len); this->rev = 0 ; } block<ElemType>* newblock = new block<ElemType>(this->next,this); if( this->next != NULL )this->next->pre = newblock ; this->next = newblock ; /*注意修改一些基本的field*/ newblock->len = len - pos ; newblock->setData(data+pos,len-pos);/*赋值*/ this->len = pos ;/*完成[0,pos)的分裂*/ }
③:合并
本块合并掉下一块
bool Union()/*当下一块和本块数据之和 < maxn 的时候可以合并*/ { block<ElemType>* nextBlock = this->next ; if( nextBlock == NULL ) return false ; if( nextBlock->len + this->len > maxn ) return false ; /*合并*/ if( this->rev ) { reverse(this->data,this->data+this->len); this->rev = 0 ; } if( nextBlock->rev ) { reverse(nextBlock->data,nextBlock->data+nextBlock->len); nextBlock->rev = 0 ; } this->next = nextBlock->next ; if( nextBlock->next != NULL ) nextBlock->next->pre = this ; int i ; for( i = 0 ; i < nextBlock->len ; i++) data[this->len++] = nextBlock->data[i] ; delete nextBlock; return true ; }
④:删除
void del()/*delete the next block*/ { block<ElemType> * nextBlock = this->next ; if( nextBlock == NULL ) return ; this->next = nextBlock->next ; if( nextBlock->next != NULL )nextBlock->next->pre = this ; delete nextBlock ; }
这里就是一个链表,节点为block,针对具体情况有不同的操作。
附个editor和反转列表完整代码(合并在一起了)
#include <stdio.h>#include <ctype.h>#include <string.h>#include <iostream>#include <string>#include <math.h>#include <time.h>#include <vector>#include <queue>#include <algorithm>#define showArray(a,len) for( i = 0 ; i < len ; i++) printf("%d ",*(a+i)); puts("");/************************************************************************//* 块状链表 *//************************************************************************/using namespace std;/* insert 3 1 2 3 insert 3 1 2 3 delete 3 show 9*/const int MAXN = 300 ;template<class ElemType>class block{ public: static int maxn ; ElemType data[MAXN]; int len ;/*本block有效数据的长度*/ bool rev ; block<ElemType> *next , *pre ; block<ElemType>(block<ElemType>* to,block<ElemType>* p):next(to),pre(p) { len = 0 ; rev = false ; } /*注意pos=0,len的情况 1 <= pos < len */ void split(int pos)/*分裂,在pos处,分裂成->[0,pos)->[pos,len)->*/ { if( pos >= len || pos <= 0 ) return ;/*非法位置*/ if( this->rev ) { reverse(this->data,this->data+this->len); this->rev = 0 ; } block<ElemType>* newblock = new block<ElemType>(this->next,this); if( this->next != NULL )this->next->pre = newblock ; this->next = newblock ; /*注意修改一些基本的field*/ newblock->len = len - pos ; //strcpy((char*)newblock->data,(char*)&data[pos]);/*完成[pos,len)的分裂*/ newblock->setData(data+pos,len-pos); this->len = pos ;/*完成[0,pos)的分裂*/ } bool Union()/*当下一块和本块数据之和 < maxn 的时候可以合并*/ { block<ElemType>* nextBlock = this->next ; if( nextBlock == NULL ) return false ; if( nextBlock->len + this->len > maxn ) return false ; /*合并*/ if( this->rev ) { reverse(this->data,this->data+this->len); this->rev = 0 ; } if( nextBlock->rev ) { reverse(nextBlock->data,nextBlock->data+nextBlock->len); nextBlock->rev = 0 ; } this->next = nextBlock->next ; if( nextBlock->next != NULL ) nextBlock->next->pre = this ; //strcpy((char*)&this->data[len],(char*)nextBlock->data); int i ; for( i = 0 ; i < nextBlock->len ; i++) data[this->len++] = nextBlock->data[i] ; delete nextBlock; return true ; } ElemType select(int k) { if( k < len && k >= 0 ) return data[k] ; return 0 ; } void del()/*delete the next block*/ { block<ElemType> * nextBlock = this->next ; if( nextBlock == NULL ) return ; this->next = nextBlock->next ; if( nextBlock->next != NULL )nextBlock->next->pre = this ; delete nextBlock ; } void setData(ElemType array[],int len) { this->len = len ; int i ; for( i = 0 ; i < len ; i++) this->data[i] = array[i] ; }};template<class ElemType>int block<ElemType>::maxn = MAXN ;template<class ElemType>class CBlockList{public: block<ElemType>* head ; block<ElemType>* cur ;/*指向当前的block*/ int offset ;/*block内偏移*/ CBlockList<ElemType>() { head = new block<ElemType>(NULL,NULL); cur = head ; offset = -1 ; } /*一下是NOI2003 editor要求的操作*/ /*指针到第pos个位置去*/ void moveKth(int pos); /*指针前移*/ void PREV(); /*指针前移*/ void NEXT(); /*输出指针后n个字符,指针位置不变*/ void get(int n); /*删除指针后n个字符*/ void del(int n); /*在指针后插入n个字符*/ void insert(ElemType array[],int n);};template<class ElemType>void CBlockList<ElemType>::moveKth(int pos){ block<ElemType> *temp = head->next , *fa = head ; int accumulation = 0 ; while ( temp != NULL ) { if( accumulation + temp->len >= pos ) break ; fa = temp ;/*去掉fa faster*/ accumulation += temp->len ; temp = temp->next ; } if( temp == NULL ) /*超出边界后,默认指向最后一个元素*/ { cur = fa ; this->offset = cur->len - 1 ;/*note:if there is no data in blocklist , offset = -1 */ } else { cur = temp ; this->offset = pos - accumulation - 1 ; } if( cur != NULL ) while(cur->Union());}template<class ElemType>void CBlockList<ElemType>::PREV(){ if( this->offset == -1 ) { /*initial cur and offset */ if( head->next != NULL ) cur = head->next ; } else if( this->offset == 0 ) /*go to pre block's last data*/ { if( cur != head->next ) /*if equals, there is no previous data*/ { cur = cur->pre ; this->offset = cur->len - 1 ; } else this->offset--; } else { this->offset--; } if( cur != NULL ) while(cur->Union());}template<class ElemType>void CBlockList<ElemType>::NEXT(){ if( this->offset == -1 ) { /*initial cur and offset */ if( head->next != NULL ) cur = head->next , this->offset = 0 ; } else if( this->offset == cur->len - 1 ) /*go to pre block's last data*/ { if( cur->next != NULL ) /*if not , there's no next data*/ { cur = cur->next ; this->offset = 0 ; } } else { this->offset++; } if( cur != NULL ) while(cur->Union());}template<class ElemType>void CBlockList<ElemType>::get(int n){ if( this->offset == -1 ) { /*initial cur and this->offset */ if( head->next == NULL ) return ; cur = head->next ; } block<ElemType> *temp ; int i , pos ; temp = cur ; for ( i = 0 , pos = this->offset + 1 ; i < n ; i++,pos++) { if( pos == temp->len ) { temp = temp->next ; if( temp == NULL ) break; pos = 0 ; } if( temp != NULL ) printf("%c",temp->select(pos)); } puts("");}template<class ElemType>void CBlockList<ElemType>::insert(ElemType array[],int n){ if( n <= 0 ) return ; block<ElemType>* father , *next ; if ( this->offset == -1 ) { /*insert into the first block*/ next = head->next ;/*insert before head*/ father = head ; } else { /*split */ cur->split(this->offset+1); next = cur->next ; father = cur ; } int len , accumulation = 0 ; do { block<ElemType>* newBlock = new block<ElemType>(NULL,father); if( n > block<ElemType>::maxn ) len = block<ElemType>::maxn ; else len = n ; newBlock->setData(array+accumulation,len); //newBlock->pre = father ; /*father must not empty*/ father->next = newBlock ; father = newBlock ; n -= len ; accumulation += block<ElemType>::maxn ; } while ( n > 0 ) ; father->next = next ; /*总是成对出现的,不要总忘了*/ if( next != NULL ) next->pre = father ; /*note:revise cur*/ if( this->offset == -1 ) cur = head->next ; if( cur != NULL ) while(cur->Union());}template<class ElemType>void CBlockList<ElemType>::del(int n){ if( this->offset == -1 ) { /*initial cur and offset */ if( head->next == NULL ) return ; cur = head ; } else { /*先分割,分割时前pos个data在一起*/ cur->split(this->offset+1); } int accumulation = 0 ; block<ElemType>* temp = cur->next ; while ( temp != NULL ) { if( temp->len + accumulation <= n ) { /*delete the temp block*/ accumulation += temp->len ; temp = temp->next ; cur->del(); } else { /*split temp block*/ if( n > accumulation ) { temp->split(n-accumulation); cur->del(); } break ; } } if( this->offset == -1 ) cur = head->next ; /*合并*/ /*!!!找了半个多小时才找到的错误= =*/ if( cur != NULL )while(cur->Union());}/************************************************************************//* editor指令操作: *//* insert X *//* delete X *//* goto X *//* pre *//* next *//* show X *//************************************************************************/class CEditor{public: const int maxn ; CEditor():maxn(1024*1024*2) { } char array[1024*1024*2+10]; CBlockList<char> list ; void handle() { char op[16] , ch ; int i , x , pos , t; scanf("%d",&t); while(t--) { scanf("%s",op); switch(tolower(op[0])) { case 'i': scanf("%d",&x); for( i = 0 ; i < x ; ) { ch = getchar(); if( ch >= 32 && ch <= 126 ) array[i++] = ch ; } list.insert(array,x); break; case 'm': scanf("%d",&pos); list.moveKth(pos); break; case 'p': list.PREV(); break; case 'n': list.NEXT(); break; case 'g': scanf("%d",&x); list.get(x); break; case 'd': scanf("%d",&x); list.del(x); break; default: ; } } }};template<class ElemType>class CRevBlockList: public CBlockList<ElemType>{public: void build(int n); void rev(int l,int r); void show();};template<class ElemType>void CRevBlockList<ElemType>::rev(int l,int r){ this->moveKth(l-1); block<ElemType> *temp = this->cur , *curNext , *tmp ; this->cur->split(this->offset+1); /*注意这种未分割的情况!!!*/ if( this->offset == -1 ) temp = this->cur->pre ; this->moveKth(r); this->cur->split(this->offset+1); /*reverse (temp,cur] */ curNext = this->cur->next ; temp->next = this->cur ; tmp = temp ; //if( this->cur == temp ) this->cur->rev ^= 1 ; while ( this->cur != tmp ) { this->cur->rev ^= 1 ; temp->next = this->cur ; this->cur->next = this->cur->pre ; if( this->cur->pre != NULL ) this->cur->pre = temp ; temp = this->cur ; this->cur = this->cur->next ; } temp->next = curNext ; if( curNext != NULL ) curNext->pre = temp ;}template<class ElemType>void CRevBlockList<ElemType>::show(){ int i ; block<ElemType>* tmp = this->head->next ; while ( tmp != NULL ) { if( tmp->rev ) { for( i = tmp->len - 1 ; i >= 0 ; i--) printf("%d ",tmp->data[i]); } else { for( i = 0 ; i < tmp->len ; i++) printf("%d ",tmp->data[i]); } tmp = tmp->next ; } puts("");};template<class ElemType>void CRevBlockList<ElemType>::build(int n){ int i , j ; block<ElemType>* tmp = new block<ElemType>(NULL,this->head) , *fa ; fa = this->head ; fa->next = tmp ; for( i = 1 ; i <= n ; i++) { if( tmp->len == block<ElemType>::maxn ) { fa = tmp ; tmp = new block<ElemType>(NULL,fa) ; fa->next = tmp ; i--; } else { tmp->data[tmp->len++] = i ; } }};class CRevClient{public: CRevBlockList<int> list ; void handle() { int n , m , l , r ; while (~scanf("%d%d",&n,&m)) { list.build(n); while (m--) { scanf("%d%d",&l,&r); list.rev(l,r); } list.show(); } }};int main(){ CRevClient client ; client.handle();}
- 块状链表之代码剖析
- 块状链表之代码分析
- 块状链表 代码小记
- 数据结构之块状链表
- 数据结构之块状链表
- 苏煜块状链表代码。。
- 数据结构与算法之:块状链表(或者叫块状数组)
- 块状链表
- 块状链表 poj2887
- 块状链表
- 数据结构:块状链表
- 数据结构:块状链表
- java 块状链表
- 块状链表
- 块状链表
- 块状链表
- *块状链表
- POJ2887【块状链表】
- [转]C语言程序的存储区域
- HDOJ 1907
- ASP.NET MVC3 DropDownList 验证问题
- php简单强制下载
- 高斯图像滤波原理及其编程离散化实现方法
- 块状链表之代码剖析
- undefined reference to涉及的链接问题
- 三个表左边接的sql查询
- MySQL外键示例
- 我都懂得 真的都懂
- HTML5开发关注
- TabHost的中第一个tab中button点击跳转到第二个tab的解决办法
- Spring中应用占位符需引入的配置
- Java正则表达式应用