Merge pull request #145 from MrPHQ/master

跳表的C++版本,翻译JAVA版本,有详细注释
This commit is contained in:
wangzheng0822 2018-11-12 10:44:38 +08:00 committed by GitHub
commit 735b963878
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,363 @@
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <cstring>
#include <random>
#include <ctime>
using namespace std;
/**
*
*
*
* C++.
* JAVA版本 AuthorZHENG
*
* Authorpuhuaqiang
*
* :
*
* K级 1 9
* K-1 1 5 9
* K-2 1 3 5 7 9
* ... ....
* 0() 1 2 3 4 5 6 7 8 9
*/
const int MAX_LEVEL = 16;
/**
* @brief
*/
class CNode
{
public:
CNode();
~CNode();
std::string toString();
/**
* @brief
*/
CNode** GetIdxList();
/**
* @brief
*/
void SetData(int v);
/**
* @brief
*/
int GetData();
/**
* @brief
*/
void SetLevel(int l);
private:
/**当前节点的值*/
int m_data;
/**
* .
* 2 N1 N2
* 1 N1 N2
* N1是本节点, m_lpForwards[x] N2
*
* [0] .
*/
CNode* m_lpForwards[MAX_LEVEL];
/**当前节点的所在的最大索引级别*/
int m_iMaxLevel;
};
/**
* @brief
*/
class CSkipList
{
public:
CSkipList();
~CSkipList();
/**
* @brief
* @param v
*/
CNode* Find(int v);
/**
* @brief
* @param v
*/
void Insert(int v);
/**
* @brief
* @param v
*/
int Delete(int v);
void PrintAll();
/**
* @brief
* @param l -1 >=0
*/
void PrintAll(int l);
/**
* @brief ,K级的随机函数
* @return K
*/
int RandomLevel();
private:
int levelCount;
/**
*
* /()
*/
CNode* m_lpHead;
};
int main()
{
CSkipList skipList;
/// 插入原始值
for(int i=1; i< 50; i++){
if((i%3) == 0){
skipList.Insert(i);
}
}
for(int i=1; i< 50; i++){
if((i%3) == 1){
skipList.Insert(i);
}
}
skipList.PrintAll();
std::cout<<std::endl;
/// 打印所有等级结构
skipList.PrintAll(-1);
/// 查找
std::cout<<std::endl;
CNode* lpNode = skipList.Find(27);
if(NULL != lpNode){
std::cout<<"查找值为27的节点,找到该节点,节点值:"<<lpNode->GetData()<<std::endl;
}else{
std::cout<<"查找值为27的节点,未找到该节点"<<std::endl;
}
/// 删除
std::cout<<std::endl;
int ret = skipList.Delete(46);
if(0 == ret){
std::cout<<"查找值为46的节点,找到该节点,并删除成功"<<std::endl;
}else{
std::cout<<"查找值为46的节点,找到该节点,删除失败"<<std::endl;
}
std::cout<<std::endl;
//打印所有等级结构
skipList.PrintAll(-1);
std::cin.ignore();
return 0;
}
CNode::CNode()
{
m_data = -1;
m_iMaxLevel = 0;
for(int i=0; i<MAX_LEVEL; i++){
m_lpForwards[i] = NULL;
}
}
CNode::~CNode()
{
}
CNode** CNode::GetIdxList()
{
return m_lpForwards;
}
void CNode::SetData(int v)
{
m_data = v;
}
int CNode::GetData()
{
return m_data;
}
void CNode::SetLevel(int l)
{
m_iMaxLevel = l;
}
std::string CNode::toString()
{
char tmp[32];
std::string ret;
ret.append("{ data: ");
sprintf(tmp, "%d", m_data);
ret.append(tmp);
ret.append("; levels: ");
sprintf(tmp, "%d", m_iMaxLevel);
ret.append(tmp);
ret.append(" }");
return ret;
}
CSkipList::CSkipList()
{
levelCount = 1;
m_lpHead = new CNode();
}
CSkipList::~CSkipList()
{
}
CNode* CSkipList::Find(int v)
{
CNode* lpNode = m_lpHead;
/**
* .
* K -> k-1 -> k-2 ...->0
*/
for(int i=levelCount-1; i>=0; --i){
/**
* v的节点(lpNode).
*/
while((NULL != lpNode->GetIdxList()[i]) && (lpNode->GetIdxList()[i]->GetData() < v)){
lpNode = lpNode->GetIdxList()[i];
}
}
/**
* lpNode v的节点, lpNode的下一个节点就等于或大于v的节点
*/
if((NULL != lpNode->GetIdxList()[0]) && (lpNode->GetIdxList()[0]->GetData() == v)){
return lpNode->GetIdxList()[0];
}
return NULL;
}
void CSkipList::Insert(int v)
{
/// 新节点
CNode* lpNewNode = new CNode();
if(NULL == lpNewNode){
return;
}
/**
*
* 3, 123
*/
int level = RandomLevel();
lpNewNode->SetData(v);
lpNewNode->SetLevel(level);
/**
*
*
*/
CNode *lpUpdateNode[level];
for(int i=0; i<level; i++){
/// 每个索引链表的头节点
lpUpdateNode[i] =m_lpHead;
}
CNode* lpFind = m_lpHead;
for(int i= level-1; i >= 0; --i){
/**
*
* eg. 1 1 7 10
* 6
* lpFind->GetIdxList()[i]->GetData() : lpFind在第1级索引的下一个节点的数据
* "lpFind->GetIdxList()[i]->GetData() < v",
* lpFind节点的后面, lpFind->GetIdxList()[i]
* lpFind就是1 lpFind->GetIdxList()[i] 7
*/
while((NULL != lpFind->GetIdxList()[i]) && (lpFind->GetIdxList()[i]->GetData() < v)){
lpFind = lpFind->GetIdxList()[i];
}
/// lpFind 是新节点在 第i级索引链表的后一个节点
lpUpdateNode[i] = lpFind;
}
for(int i=0; i<level; ++i){
/**
*
* eg 1 1 7 10
* 6.
* lpUpdateNode[i] 1; lpUpdateNode[i]->GetIdxList()[i]7
*
* 2 6 17
*/
lpNewNode->GetIdxList()[i] = lpUpdateNode[i]->GetIdxList()[i];
lpUpdateNode[i]->GetIdxList()[i] = lpNewNode;
}
if(levelCount < level){
levelCount = level;
}
}
int CSkipList::Delete(int v)
{
int ret = -1;
CNode *lpUpdateNode[levelCount];
CNode *lpFind = m_lpHead;
for(int i=levelCount-1; i>= 0; --i){
/**
* v的节点(lpFind).
*/
while((NULL != lpFind->GetIdxList()[i]) && (lpFind->GetIdxList()[i]->GetData() < v)){
lpFind = lpFind->GetIdxList()[i];
}
lpUpdateNode[i] = lpFind;
}
/**
* lpFind v的节点, lpFind的下一个节点就等于或大于v的节点
*/
if((NULL != lpFind->GetIdxList()[0]) && (lpFind->GetIdxList()[0]->GetData() == v)){
for(int i=levelCount-1; i>=0; --i){
if((NULL != lpUpdateNode[i]->GetIdxList()[i]) && (v == lpUpdateNode[i]->GetIdxList()[i]->GetData())){
lpUpdateNode[i]->GetIdxList()[i] = lpUpdateNode[i]->GetIdxList()[i]->GetIdxList()[i];
ret = 0;
}
}
}
return ret;
}
void CSkipList::PrintAll()
{
CNode* lpNode = m_lpHead;
while(NULL != lpNode->GetIdxList()[0]){
std::cout<<lpNode->GetIdxList()[0]->toString().data()<<std::endl;
lpNode = lpNode->GetIdxList()[0];
}
}
void CSkipList::PrintAll(int l)
{
for(int i=MAX_LEVEL-1; i>=0;--i){
CNode* lpNode = m_lpHead;
std::cout<<""<<i<<"级:"<<std::endl;
if((l < 0) || ((l >= 0) && (l == i))){
while(NULL != lpNode->GetIdxList()[i]){
std::cout<<lpNode->GetIdxList()[i]->GetData()<<" ";
lpNode = lpNode->GetIdxList()[i];
}
std::cout<<std::endl;
if(l >= 0){
break;
}
}
}
}
int GetRandom()
{
static int _count = 1;
std::default_random_engine generator(time(0) + _count);
std::uniform_int_distribution<int> distribution(1,99999/*0x7FFFFFFF*/);
int dice_roll = distribution(generator);
_count += 100;
return dice_roll;
}
int CSkipList::RandomLevel()
{
int level = 1;
for(int i=1; i<MAX_LEVEL; ++i){
if(1 == (GetRandom()%3)){
level++;
}
}
return level;
}