学习C++有一周了,今天用C++设计了一个双向链表,这个链表有排序功能,默认按升序排列,接受的参数可以是数字,也可以是字符串。现在把自己写的代码,分享出来。如果链表中接受的对象为Lexeme,可以用于存储中文分词机械化分词后的结果集。

QuickSortSet.h

#ifndef DOUBLE_LINK_H_INCLUDED
#define DOUBLE_LINK_H_INCLUDED
#include<iostream>
class QuickSortSet
{

//双向链表节点
public: class Node
{
public:
Node* next;
public:
Node* pre;
const void* value;
Node(const void* val)
{
value = val;
next = pre = nullptr;
}
};
public:

//constructor
QuickSortSet(int qs = CAPACITY);
//析构函数
~QuickSortSet();
//赋值运算符
QuickSortSet& operator=(const QuickSortSet& qs)
{
return *this;
}

//链表的大小
int size();

//比较节点值的大小,仅限于数字和字符串
int compare(const void* a,const void* b);

//将"value"插入到链表,成功返回0,否则返回-1
int insert(const void *pval);

//返回链表的第一个元素
const void* peekFirst();
//返回链表的最后一个元素
const void* peekLast();

//取出链表的第一个元素
const void* pollFirst();
//取出链表的最后一个元素
const void* pollLast();

bool isEmpty()
{
return count == 0;
}
bool isFull()
{
return count == qSize;
}

Node* getHead()
{
return head;
}
Node* getTail()
{
return tail;
}

private:
enum {CAPACITY = 1 << 30 -1};
const int qSize;
int count;

//链表头部和尾部
Node* head;
Node* tail;
};
#endif // DOUBLE_LINK_H_INCLUDED

QuickSortSet实现:

#include<iostream>
#include<cctype>
#include<cstring>
#include "double_link.h"
using namespace std;

/**
* 构造函数,默认容量为CAPACITY
*/
QuickSortSet::QuickSortSet(int qs):qSize(qs){
head = tail = nullptr;
count = 0;
}
/**
* 析构函数,默认容量为CAPACITY
*/
QuickSortSet::~QuickSortSet(){
QuickSortSet::Node* temp;
while(head){
temp = head;
head = head->next;
delete temp->value;
delete temp;
}
}

/**
* 返回链表的大小
* \return count
*/
int QuickSortSet::size()
{
return count;
}
/**
* 比较节点值的大小,仅限于数字和字符串
*/
int QuickSortSet::compare(const void* a,const void* b)
{
if (isdigit(*(int*)a))
{
return (*(int*)a) - (*(int*)b);
}
else
{
int i = 0,j = 0;
while (((const char*)a)[i] && ((const char*)b)[j])
{
if (((const char*)a)[i] - ((const char*)b)[j] != 0)
{
return ((const char*)a)[i] - ((const char*)b)[j];
}
i++,j++;
}
if (strlen((const char*)a) == i && strlen((const char*)b) == j)
{
return 0;
}
else if (strlen((const char*)a) == i)
{
return 1;
}
else
{
return -1;
}

}

}

/**
* 将"value"插入到链表,成功返回0,否则返回-1
*/
int QuickSortSet::insert(const void *pval)
{
Node* n;
//1.链表为空时
if (isEmpty())
{
n = new Node(pval);

head = tail = n;
count ++;
return 1;
}
if (isFull()) {return -1;}

//2.如果链表不为空,进行比较,确定位置
if (compare(head->value,pval) > 0) //在head前面
{
n = new Node(pval);
n->next = head;
head->pre = n;
head = n;
count++;
return 1;
}
else if (compare(tail->value,pval) < 0) //tail后面
{
n = new Node(pval);
tail->next = n;
n->pre = tail;
tail = n;
count++;
return 1;
}
else //位于head和tail之间的某一个位置
{
Node* index = tail;
while(compare(index->value,pval) > 0)
{
index = index->pre;
}
n = new Node(pval);

n->pre = index;
n->next = index->next;
index->next->pre = n;
index->next = n;

count++;
return 1;
}
return -1;
}
/**
* 返回链表的第一个元素
*/
const void* QuickSortSet::peekFirst()
{
return head == NULL ? NULL : head->value;
}
/**
* 取出链表的第一个元素
*/
const void* QuickSortSet::pollFirst()
{
Node* temp = head;
const void* value = temp->value;
head = head->next;
delete temp->value;
delete temp;
return value;
}

/**
* 返回链表的最后一个元素
*/
const void* QuickSortSet::peekLast(){
return tail == nullptr ? nullptr : tail->value;
}

/**
* 取出链表的最后一个元素
*/
const void* QuickSortSet::pollLast(){
Node* temp = tail;
const void* value = temp->value;
tail = tail->pre;
delete temp->value;
delete temp;
return value;
}

测试类:

#include<cstdlib>
#include<iostream>
#include "heap.h"
#include "double_link.h"
#include "time.h"
#include<fstream>
#define DEBUG 1
#define SIZE 5
#define LINE 10000000
using namespace std;
void testNum();
void testStr();
//void testHeap();
//void createFile();
int main()
{
#if DEBUG
//testNum();
testStr();
#endif // DEBUG
//createFile(); //生成随机数文件
// testHeap();
}
#if DEBUG
void testNum()
{
QuickSortSet q = QuickSortSet();

int num = 12;
q.insert(&num);

const int num1 = 3;
q.insert(&num1);

const int num2 = 9;
q.insert(&num2);

QuickSortSet::Node* node = q.getHead();
while(node){
cout << *((int*)node->value) << endl;
node = node->next;
}
}
void testStr()
{
QuickSortSet q = QuickSortSet();

q.insert("abc");
q.insert("abce");
q.insert("abcd");
q.insert("abcf");

QuickSortSet::Node* node = q.getHead();

while(node){
cout << (const char*)node->value << endl;
node = node->next;
}
}
#endif // DEBUG

/**
* 1.生成随机数文件;
* 2.读取前SIZE行,构造小根堆;
* 3.依次读取剩余的行,对读到的每行数据,如果比堆顶元素大,替换之,然后调整小根堆;
* 4.读取结束后,执行堆排序。
*/
void testHeap()
{

clock_t start,finish;
double duration;//耗时时间
start = clock();

ifstream inFile;
inFile.open("E:\\var\\logs\\nums.txt");

int nums[SIZE];
int index = 0;
char num[1024] = {0};
while (inFile.getline(num,sizeof(num)))
{
nums[index++] = atoi(num);
if (index == SIZE)
{
break;
}
}
createMinHeap(nums,SIZE);//读取前SIZE行,构造小根堆

int temp;
while (inFile.getline(num,sizeof(num)))
{
temp = atoi(num);
if (temp > nums[0])
{
nums[0] = temp;
adjustment(0);
}
}//依次读取剩余的行,对读到的每行数据,如果比堆顶元素大,替换之,然后调整小根堆

heapSort();//读取结束后,执行堆排序

finish = clock();
duration = (double)((finish - start) / CLOCKS_PER_SEC);
cout << "耗时 " << duration << "s." << endl;
for (int i = 0; i < SIZE; i++)
{
cout << nums[i] << " ";
}
}
/**
* 产生随机数文件
*/
void createFile()
{
ofstream outFile;
outFile.open("E:\\var\\logs\\nums.txt");
srand((unsigned)time(NULL));
for (int i = 0; i <= LINE; i++)
{
outFile << rand() << endl;
}
}
void safeDelete(){

}

输出结果:

abcd

abce

abcf

abc

原创:C++实现的可排序的双向链表的更多相关文章

  1. MS - 1 - 把二元查找树转变成排序的双向链表

    ## 1. 把二元查找树转变成排序的双向链表 ## ### 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表. ### 要求不能创建任何新的结点,只调整指针的指向. 10       ...

  2. 1.把二元查找树转变成排序的双向链表[BST2DoubleLinkedList]

    [题目]:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树 . 10 / \ 6 14 / \ / \ 4 8 12 16 转 ...

  3. 二元查找树转变成排序的双向链表之C#算法实现

    此题为July在CSDN发布的微软编程面试100题中的第一题,觉得蛮有趣的,今天也拿过来玩玩,July的代码用的是C++实现,可能因为有指针的原因吧,感觉看起来相对比较容易理解整个的实现过程,而我,试 ...

  4. 【Data structure & Algorithm】把二元查找树转变成排序的双向链表

    把二元查找树转变成排序的双向链表 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,要求不能创建任何新节点,只调整指针指向. 比如将二元查找树 10 /       \ 6       ...

  5. 剑指offer26:将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

    1 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2 思路和方法 在二叉搜索树中,每个结点都有两个分别指向其左.右子树的 ...

  6. [个人原创]关于java中对象排序的一些探讨(三)

    这篇文章由十八子将原创,转载请注明,并标明博客地址:http://www.cnblogs.com/shibazijiang/ 对对象排序也可以使用Guava中的Ordering类. 构造Orderin ...

  7. 1.Go语言copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() ...

  8. 1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表

    1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 ? 1 2 3 4 5 6 7 8 9 10 11 12 package main   imp ...

  9. [置顶] 原创鼠标拖动实现DIV排序

    先上效果图: 对比传统的排序,这是一个很不错的尝试,希望对大家有启发. 大家可以参考我的上一篇博文:http://blog.csdn.net/littlebo01/article/details/12 ...

随机推荐

  1. springMvc之常用注解介绍

    @requestbody和@requestparam的用法  获取请求参数的方法 get请求: 直接获取request    如: public String getHtml(HttpServletR ...

  2. Java序列化流

    1.什么是序列化流 序列化就是把Java对象“流化”,序列化后的Java对象可以保存到本地文件系统,或者通过Socket传输到其他的服务器. Java中对象序列化有以下特点: 1)类实现java.io ...

  3. 用不上索引的sql

    1.使用不等于操作符(<>, !=) 大于可以.小于可以,between and 也可以 2.使用 is null 或 is not null 任何包含null值的列都将不会被包含在索引中 ...

  4. chrome滚动条颜色尺寸设置

    <style> /*chrome滚动条颜色设置*/ *::-webkit-scrollbar { width: 5px; height: 10px; background-color: t ...

  5. UTF-8 中文编码范围

    主流的匹配字符有两种 [\u4e00-\u9fa5]和[\u2E80-\u9FFF],后者范围更广,包括了日韩地区的汉字 import re pattern = re.compile("[\ ...

  6. 【JUC】7.CountDownLatch

    Latch:门闩.一种线程通信的方式:当程序不涉及同步,仅仅需要线程通信的时候,使用synchronize或者lock的线程通信等待唤醒机制,就显得太重了: 这时候,可以考虑使用信号量类:CountD ...

  7. mysql 压力测试工具sysbench

    2.1 只读示例 ./bin/sysbench --test=/usr/share/sysbench/tests/include/oltp_legacy/oltp.lua --mysql-host=1 ...

  8. 使用ansible部署CDH 5.15.1大数据集群

    使用ansible离线部署CDH 5.15.1大数据集群 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在此之前,我之前分享过使用shell自定义脚本部署大数据集群,不管是部署CD ...

  9. linux-秘钥生成

    服务器sshd配置 #vim /etc/ssh/sshd_conf PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys # ...

  10. 个人第5次作业:Alpha2项目的测试

    这个作业属于哪个课程 <课程的链接> 这个作业要求在哪里 <作业要求的链接> 名字 易林 学号 201731062134 团队名称 <巧克力王子和六个小矮人> 第一 ...