关于跳表的读书笔记

原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。

由于各种原因,可能存在诸多不足,欢迎斧正!       

      之前不知道还有跳表这等数据结构,直到做到一个题要分析跳表的插入、删除等基本操作的时间复杂度,于是查阅资料写了个跳表的程序。跳表本质上是有序表,但是一种基于概率的有序表。

        直接在单链表上查找某元素时间复杂度为O(n)。

clip_image001

 

        但基于跳表的查找时间复杂度为O(log(n)),以空间换取时间。通过高层建立索引,达到加快查找的目的。

 

clip_image005

跳表具有如下性质:

        (1)、跳表是有序链表

        (2)、若某元素出现在i层上,则一定出现在i-1层上,i>.1;

        (3)、某节点有横向和纵向两个指针。

        以上图片来自http://blog.sina.com.cn/s/blog_72995dcc01017w1t.html,在此致谢!

 

#include<iostream>
#include<ctime>
using namespace std;

const int MAXN_LEVEL=10;

struct SNode
{
	int key;
	SNode *forword[MAXN_LEVEL];
};

struct SkipList
{
	int nowLevel; 
	SNode *head;
};



/************************************************
*参数:myList为指向跳表头结点的指针
*功能:初始化跳表
*************************************************/
void InitSkipList(SkipList *& myList)
{
	 myList=new SkipList;
	 myList->nowLevel=0;
	 myList->head=new SNode;
	 for(int i=0;i<MAXN_LEVEL;i++)
		 myList->head->forword[i]=NULL;
}

/************************************************
*参数:myList为指向跳表头结点的指针,x为待插入元素,countRet为查找次数
*功能:在跳表中插入元素x
*************************************************/
bool InsertSkipList(SkipList *myList,int val)
{
	if(NULL==myList)
		return false;
	int k=myList->nowLevel;
	SNode *q,*p=myList->head;
	SNode *upDateNode[MAXN_LEVEL];
	while(k>=0)
	{
		q=p->forword[k];
		while(NULL!=q&&q->key<val)
		{
			p=q;
			q=p->forword[k];
		}
		if(NULL!=q&&q->key==val)
		     return false;
		upDateNode[k]=p;
		--k;
	}
	k=rand()%(MAXN_LEVEL-1);
	if(k>myList->nowLevel)
	{
		k=++myList->nowLevel;
		upDateNode[k]=myList->head;
	}
	p=new SNode;
	p->key=val;
	for(int i=0;i<=k;i++)
	{
		q=upDateNode[i];//q指向前面小于x的
		p->forword[i]=q->forword[i];
		q->forword[i]=p;
	}
	//for(int i=k+1;i<=myList->nowLevel;i++)
	 for(int i=k+1;i<MAXN_LEVEL;i++)
	        p->forword[i]=NULL;
	return true;
}

/************************************************
*参数:myList为指向跳表头结点的指针,x为待查找元素,countRet为查找次数
*功能:查找跳表中是否存在元素x
*************************************************/
SNode* FindSkipList(SkipList * myList,int val,int &countRet)
{
	if(NULL==myList)
		return NULL;

	int k=myList->nowLevel;
	SNode *q,*p=myList->head;
	while(k>=0)
	{
		q=p->forword[k];
		++countRet;
		while(NULL!=q&&q->key<val)
		{
			++countRet;
			p=q;
			q=p->forword[k];
		}
		if(NULL!=q&&q->key==val)
		    return q;
		--k;
	}
	return NULL;
}

/************************************************
*参数:myList为指向跳表头结点的指针,x为待删除元素
*功能:删除跳表中元素x
*************************************************/
bool DeleteSkipList(SkipList * myList,int val)
{
	int tmpCountRet=0;
	SNode *ret=FindSkipList(myList,val,tmpCountRet);
	if(NULL==ret)
		return false;

	int k=myList->nowLevel;
	SNode *q,*p=myList->head;
	SNode *upDateNode[MAXN_LEVEL];

	 for(int i=0;i<MAXN_LEVEL;i++)
		upDateNode[i]=NULL;
	
	while(k>=0)
	{
		q=p->forword[k];
		while(NULL!=q&&q->key<val)
		{
			p=q;
			q=p->forword[k];
		}
		if(NULL!=q&&q->key==val)
			 upDateNode[k]=p;
		--k;
	}

	for(int i=0;i<=myList->nowLevel;i++)
	{
		q=upDateNode[i];//q指向前面小于x
		if(NULL!=q&&q->forword[i]==ret)
			q->forword[i]=ret->forword[i];
	}
	delete ret;
	return true;
}



int main()
{
	int val;
	SkipList *  myList;
	InitSkipList(myList);

	while(cin>>val)
	{
		if(!InsertSkipList(myList,val))
			cout<<val<<"插入失败!"<<endl;
		else cout<<val<<"插入成功!"<<endl;
		/*
		int countRet=0;
		if(NULL!=FindSkipList(myList,val,countRet))
			cout<<val<<"查找成功!"<<endl;
		else cout<<val<<"查找失败!"<<endl;
		cout<<"共查找了"<<countRet<<"次"<<endl;
		*/
		/*
		DeleteSkipList(myList,val);
		countRet=0;
		if(NULL!=FindSkipList(myList,val,countRet))
			cout<<val<<"查找成功!"<<endl;
		else cout<<val<<"查找失败!"<<endl;
		cout<<"共查找了"<<countRet<<"次"<<endl;
		*/

	}
	system("Pause");
}


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值