数据结构与算法——跳表的实现

关于跳表的详细介绍请看数据结构与算法——跳表

本文主要介绍跳表的一种实现方式。

头文件如下:

/*
* Copyright: (c) 2019
*
* 文件名称:  SkipList.h	
* 文件标识:
* 摘	要: 跳表的一种模板实现方法,跳表中存储的是模板类型,并且存储的是不重复的
*
* 版	本: 1.0
* 作	者: RF_LYF
* 创建日期:	 2019/5/14  8:51
*/

#ifndef _SKIPLIST_H
#define _SKIPLIST_H

#include <iostream>
#define MAX_LEVEL 16

template<typename T>
class SNode
{
	typedef SNode<T>* pSNode;
public:
	SNode()
	{
		maxLevel = 0;
		forward = new pSNode[MAX_LEVEL];
		for(int i = 0; i < MAX_LEVEL; ++i)
		{
			forward[i] = NULL;
		}
	}
	~SNode()
	{
		delete []forward;
		forward = NULL;
	}
	T data;
	int maxLevel;
	pSNode *forward;
};

template<typename T>
class SkipList
{
	typedef SNode<T>* pSNode;
public:
	SkipList(void);
	~SkipList(void);

	void Insert(const T value);
	void Delete(const T value);
	pSNode Find(const T value);
	void printAll();
private:
	int randomLevel();
	void InitArr(pSNode*, int);
	void clear();
	int getRandom();
private:
	int levelCount;
	pSNode head;
};
#endif //_SKIPLIST_H

源文件如下:

/*
* Copyright: (c) 2019
*
* 文件名称:  SkipList.cpp	
* 文件标识:
* 摘	要:
*
* 版	本: 1.0
* 作	者: RF_LYF
* 创建日期:	 2019/5/14  8:50
*/

#include "SkipList.h"
#include <random>
#include <stdlib.h>
#include <time.h>

template<typename T>
SkipList<T>::SkipList(void)
{
	levelCount = 1;
	head = new SNode<T>();
}


template<typename T>
SkipList<T>::~SkipList(void)
{
	clear();
}


/**
* @brief	在跳表中插入某一数据
*
* @method:    Insert
* @access:    public 
* @param:     const T value
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/15  22:52 
*/
template<typename T>
void SkipList<T>::Insert(const T value)
{
	int level = randomLevel();
	pSNode newNode = new SNode<T>(); 
	newNode->data = value;
	newNode->maxLevel = level;

	pSNode* update = new pSNode[level];
	InitArr(update, level);
	for(int i = 0; i < level; ++i)
	{
		update[i] = head;
	}

	pSNode p = head;
	for(int i = level - 1; i >= 0; --i)
	{
		while(p->forward[i] != NULL && p->forward[i]->data < value)
			p = p->forward[i];
		update[i] = p;
	}

	for(int i = 0; i < level; ++i)
	{
		newNode->forward[i] = update[i]->forward[i];
		update[i]->forward[i] = newNode;
	}
	

	if(levelCount < level)
		levelCount = level;
	delete []update;
}


/**
* @brief	在跳表中删除某一数据
*
* @method:    Delete
* @access:    public 
* @param:     const T value
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/15  22:52 
*/
template<typename T>
void SkipList<T>::Delete(const T value)
{
	pSNode *update = new pSNode[levelCount];
	InitArr(update, levelCount);
	pSNode p = head;
	for(int i = levelCount - 1; i >= 0; --i)
	{
		while(p->forward[i] != NULL && p->forward[i]->data < value)
			p = p->forward[i];
		update[i] = p;
	}

	if(p->forward[0] != NULL && p->forward[0]->data == value)
	{
		pSNode delptr = p->forward[0];
		for(int i = levelCount - 1; i >= 0; --i)
		{
			if(update[i]->forward[i] != NULL && update[i]->forward[i]->data == value)
			{
				update[i]->forward[i] = update[i]->forward[i]->forward[i];
			}
		}
		delete delptr;
	}
	delete []update;
}


/**
* @brief	在跳表中查找某一数据
*
* @method:    Find
* @access:    public 
* @param:     const T value
* @Return:    ::pSNode
* @author:    RF_LYF
* @since:   2019/5/15  22:52 
*/
template<typename T>
typename SkipList<T>::pSNode SkipList<T>::Find(const T value)
{
	pSNode p = head;
	for(int i = levelCount - 1; i >=0; --i)
	{
		while(p->forward[i] != NULL && p->forward[i]->data < value)
		{
			p = p->forward[i];
		}
	}
	if(p->forward[0] != NULL && p->forward[0]->data == value)
		return p->forward[0];
	else
		return NULL;
}


/**
* @brief	随机确定跳表更新的层数
*
* @method:    randomLevel
* @access:    private 
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/15  22:52 
*/
template<typename T>
int SkipList<T>::randomLevel()
{
	int level = 1;
	for(int i = 1; i < MAX_LEVEL; ++i)
	{
		if(1 == (getRandom() % 3))
		{
			level++;
		}
	}
	return level;
}


/**
* @brief	初始化数组
*
* @method:    InitArr
* @access:    private 
* @param:     typename SkipList<T>::pSNode * Arr
* @param:     int nLen
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/15  22:53 
*/
template<typename T>
void SkipList<T>::InitArr(typename SkipList<T>::pSNode* Arr, int nLen)
{
	for(int i = 0; i < nLen; ++i)
	{
		Arr[i] = NULL;
	}
}


/**
* @brief    仅用来测试
*
* @method:    printAll
* @access:    public 
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/15  22:54 
*/
template<typename T>
void SkipList<T>::printAll()
{
	for(int i = levelCount - 1; i >= 0; --i)
	{
		pSNode p = head;
		std::cout << "The " << i + 1 << " layer" << std::endl;
		while(p->forward[i] != NULL)
		{
			std::cout << p->forward[i]->data << " ";
			p = p->forward[i];
		}
		std::cout << std::endl;
	}	
}


/**
* @brief	清空跳表
*
* @method:    clear
* @access:    private 
* @Return:    void
* @author:    RF_LYF
* @since:   2019/5/15  22:53 
*/
template<typename T>
void SkipList<T>::clear()
{
	pSNode p = head;
	while(p->forward[0] != NULL)
	{
		pSNode delptr = p->forward[0];
		p->forward[0] = p->forward[0]->forward[0];
		delete delptr;
	}
	delete head;
	head = NULL;
}


/**
* @brief	获取一个随机数
*
* @method:    getRandom
* @access:    private 
* @Return:    int
* @author:    RF_LYF
* @since:   2019/5/15  22:53 
*/
template<typename T>
int SkipList<T>::getRandom()
{
	static int count = 1;
	std::default_random_engine generator(time(NULL) + count);
	std::uniform_int_distribution<int> distribution(1,99999);
	int dice_roll = distribution(generator);
	count += 100;
	return dice_roll;
}

       以上实现,当插入新数据时,通过随机函数确定需要更新的索引层,会存在下边的几层索引的结点完全一样,进而导致查找效率降低,极端情况下时间复杂度会退化为O(n),因此还需要进一步改进。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值