可以将线性表描述成一个单项循环链表,使链表的应用代码更加简洁和高效循环链表的结构如下图所示。

1,无头节点的循环链表:

2.有头节点的循环链表:

3.空列表:

将单向链表的头节点和尾节点连接起来,就成为了循环链表;

有头节点的循环链表和没有头节点的循环链表:

头节点是链表的一个附加节点,有了这个节点,空表就不用作为特殊情况来先处理了,使程序简化,有了头节点,每个链表至少包含一个节点。

使用头节点的循环链表可以使程序更加简洁,效率更高:

循环链表的实现如下:

#ifndef CIRCULAR_LIST_H
#define CIRCULAR_LIST_H
#include <iostream>#include "E:\back_up\code\c_plus_code\digui\external_file\linearlist.h"   // ABC文件
// #include "E:\back_up\code\c_plus_code\digui\external_file\chain.h"
/*
template<typename T>
struct chainNode    // 链表的节点定义
{// 数据成员 T element;chainNode<T>* next;// 定义结构体构造方法 chainNode() {};chainNode(T theElement){this->element = theElement;} chainNode(T theElement, chainNode<T>* next){this->element = theElement;this->next = next;}
}
*/template<typename T>
class circularList : public linearList<T>   // 有头的循环链表
{private:chainNode<T>* headerNode;int listSize;public:circularList(int capacity=10);   // 构造函数 circularList(const circularList& c_list);  // 拷贝构造函数~circularList();     // 析构函数//抽象数据类型ADTbool empty() const;int size() const;T& get(int index) const;int indexOf(T x) const;void erase(int index);void clear(); void insert(int index, T x);void output() const;
}; template<typename T>
circularList<T>::circularList(int capacity)
{if(capacity<1){cout << "List size invalid ";return;    // 函数结束 }headerNode = new chainNode<T>();  // 用到了chainNode的无参构造函数headerNode->next = headerNode; listSize = 0;
} template<typename T>
circularList<T>::circularList(const circularList<T>& c_list)    // 拷贝构造函数
{listSize = c_list.listSize;if(listSize == 0)    // 源链表为空       {headerNode = new chainNode<T>();headerNode->next = headerNode;return;}chainNode<T>* sourceNode = c_list.headerNode;sourceNode = sourceNode->next;   // 指向源循环链表的第一个元素headerNode = new chainNode<T>();chainNode<T>* targetNode = headerNode;targetNode->next = new chainNode<T>(sourceNode->element);   // target while(sourceNode != c_list.headerNode){sourceNode = sourceNode->next;targetNode->next = new chainNode<T>(sourceNode->element);targetNode = targetNode->next;}targetNode->next = headerNode;
}/*
析构函数没有写对,会遇到程序运行完后即使输出
结果正确,但是会陷入死循环,而且不会出现press
any key to continue
*/
template<typename T>   // 测试完璧
circularList<T>::~circularList()     // 析构函数
{chainNode<T>* sourceNode = headerNode->next;   // sourceNode指向链表的第一个元素 //sourceNode = sourceNode->next; while(sourceNode->next!=headerNode){headerNode->next = sourceNode->next;delete sourceNode;sourceNode = headerNode->next;      // sourceNode指向新的元素 //listSize--;}delete headerNode;     // 删除头节点 listSize = 0;}template<typename T>     // 测试完毕
bool circularList<T>::empty() const
{return listSize==0;
} template<typename T>   // 测试完毕
int circularList<T>::size() const
{return listSize;
}template<typename T>   // 测试完毕
T& circularList<T>::get(int index) const
{/*  if(index>listSize-1)     // 这里抛出异常最好 {cout << "The index is invalid" << endl;return;}*/chainNode<T>* sourceNode = headerNode;   // 指向链表第一个元素for(int i=0; i<=index; i++){sourceNode = sourceNode->next;}return sourceNode->element;
}template<typename T>    // 测试完毕
int circularList<T>::indexOf(T x) const    // 查找对应元素的下表
{chainNode<T>* sourceNode = headerNode->next;    // 指向链表第一个元素int cnt = 0;// bool found_flag = false;    // 标志位 while(sourceNode!=headerNode){if(sourceNode->element == x){ return cnt;}sourceNode = sourceNode->next;cnt++;}return -1;
}template<typename T>   // 测试完毕
void circularList<T>::insert(int index, T x)
{/*if(index<0 || index>listSize)    // 这里可以写return,但是应该统一为抛出异常; {return;}*/// 插入这里应该判断一些情况if(index == 0)   // 在链表首个位置插入元素{headerNode->next = new chainNode<T>(x, headerNode);  } else if(index == listSize)   // 在链表末尾插入元素{chainNode<T>* sourceNode = headerNode->next;while(sourceNode->next != headerNode){sourceNode = sourceNode->next;}// 此时sourceNOde指向最后一个元素sourceNode->next = new chainNode<T>(x, headerNode); /*for(int i=0; i<index; i++){sourceNode = sourceNode->next;}// sourceNodesourceNode = new chainNode<T>(x, headerNode);*/} else{chainNode<T>* sourceNode = headerNode;for(int i=0; i<index; i++){sourceNode = sourceNode->next;}// sourceNode指向第index-1个元素chainNode<T>* temp = sourceNode->next;sourceNode->next = new chainNode<T>(x, temp);    // 插入对应的元素 }listSize++;}template<typename T>   // 测试完毕
void circularList<T>::erase(int index)
{/*if(index<0 || index>listSize){cout << "The index is invalid" << endl;return 0;}*/if(index == 0)   // 删除链表的头节点{chainNode<T>* currentNode = headerNode->next;headerNode->next = currentNode->next;delete currentNode;} else if(index == listSize-1)    //  删除链表的尾节点{chainNode<T>* currentNode = headerNode;for(int i=0; i<index; i++){currentNode = currentNode->next;}//delete currentNode->next;chainNode<T>* deleteNode = currentNode->next;currentNode->next = headerNode;delete deleteNode;} else{chainNode<T>* sourceNode = headerNode;for(int i=0; i<index; i++){sourceNode = sourceNode->next;}// sourceNode指向链表的第index-1个元素chainNode<T>* deleteNode = sourceNode->next;   // 指向需要删除的元素 sourceNode->next = deleteNode->next;   delete deleteNode; }listSize--;
} template<typename T>    // 测试完毕
void circularList<T>::clear()    // 修改
{chainNode<T>* sourceNode = headerNode->next;while(sourceNode!=headerNode){headerNode->next = sourceNode->next;delete sourceNode;sourceNode = headerNode->next;} listSize = 0;} template<typename T>   // 测试完毕
void circularList<T>::output() const
{chainNode<T>* currentNode = headerNode;/*int cnt = 0;while(currentNode!=headerNode){cout << currentNode->element << " ";if((cnt+1)%10 == 0){cout << endl;}currentNode = currentNode->next;}cout << endl;*/    for(int i=0; i<listSize; i++){currentNode = currentNode->next;cout << currentNode->element << " ";if((i+1)%10 == 0){cout << endl;}}cout << endl;
}#endif

上述循环链表中的放方法均以通过测试:

main.cpp

#include <iostream>
#include <string>
#include <time.h>
#include "E:\back_up\code\c_plus_code\digui\external_file\linearlist.h"
#include "E:\back_up\code\c_plus_code\digui\external_file\arraylist.h"
#include "E:\back_up\code\c_plus_code\digui\external_file\chain.h"
#include "E:\back_up\code\c_plus_code\digui\external_file\circularlist.h"    // 循环链表
using namespace std;// 实现友元函数int main(int argc, char *argv[])
{circularList<double> c1(10);for(int i=0; i<10; i++){c1.insert(i, i*2);}cout << "The list size is " << c1.size() << endl;c1.output();c1.insert(3, 4.4);c1.insert(5, 3.4);cout << "The list size is " << c1.size() << endl;c1.output();circularList<double> c2;c2 = c1;cout << "The list size is " << c2.size() << endl;c2.output();c2.erase(0);c2.erase(5);cout << "The list size is " << c2.size() << endl;c2.output();/*c1.insert(3, 4.4);c1.insert(0, 1.1);cout << "The list size is " << c1.size() << endl;c1.output();c1.erase(0);c1.erase(5);cout << "The list size is " << c1.size() << endl;c1.output();circularList<double> c2;c2 = c1;cout << "The list size is " << c2.size() << endl;c2.output();return 0;
}

运行结果:

给循环链表添加方法:

1.在链表的末尾插入元素, push_back()

2.在链表的末尾删除元素:

template<typename T>
void circularList<T>::push_back(T x)
{chainNode<T>* currentNode = headerNode->next;while(currentNode->next != headerNode){currentNode = currentNode->next;}currentNode->next = new chainNode<T>(x, headerNode);listSize++;
}template<typename T>
void circularList<T>::pop_back()
{chainNode<T>* currentNode = headerNode;for(int i=0; i<listSize-1; i++){currentNode = currentNode->next;}delete currentNode->next;currentNode->next = headerNode;listSize--;
}

------------------------------------------------------------分割线------------------------------------------------------------

双向链表:

如果每个元素节点既有一个指向后继的指针,又有一个指向前驱的指针,就会方便应用,这样的链表叫做双向链表,其中每个节点都有两个指针,next和previous 。定义一个双向链表,它有两个数据成员,firstNode和 lastNode,分别指向链表的首节点和尾节点。

例如,对于链表中元素的查找工作,当index<listSize/2时从左到右查找,否则从右到左进行查找

双项链表的实现:
双向链表的节点定义:

template<typename T>
struct doubleChainNode    // 双向链表的节点定义
{T element;   // 数据域doubleChainNode<T>* previous;   // 指向前去的指针doubleChainNode<T>* next;       // 指向后继的指针// 构造函数 doubleChainNode()   {} doubleChainNode(T theElement){this->element = theElement;}doubleChainNode(T theElement, doubleChainNode<T>* thePrevious, doubleChainNode<T>* theNext){this->element = theElement;this->previous = thePrevious;this->next = theNext;}
};

双向链表类的定义:
这里的双向链表doubleChain依然作为抽象类linearList(线性表)的派生类:

#ifndef DOUBLE_CHAIN_H
#define DOUBLE_CHAIN_H
#include <iostream>
#include <string>
#include "E:\back_up\code\c_plus_code\chain\external_file\linearlist.h"   // ABC文件
#include <stddef.h>template<typename T>
struct doubleChainNode    // 双向链表的节点定义
{T element;   // 数据域doubleChainNode<T>* previous;   // 指向前去的指针doubleChainNode<T>* next;       // 指向后继的指针// 构造函数 doubleChainNode()   {} doubleChainNode(T theElement){this->element = theElement;}doubleChainNode(T theElement, doubleChainNode<T>* thePrevious, doubleChainNode<T>* theNext){this->element = theElement;this->previous = thePrevious;this->next = theNext;}
};// 定义模板类
template<typename T>
class doubleChain : public linearList<T>
{private:doubleChainNode<T>* firstNode;   // 指向链表的首节点 doubleChainNode<T>* lastNode;    // 指向链表的尾节点 int listSize;public:doubleChain(int capacity=10);  doubleChain(const doubleChain& d_chain);~doubleChain();   // 析构函数// ADT abstract data typebool empty() const;int size() const;T& get(int index) const;int indexOf(T x) const;void erase(int index);void clear(); void insert(int index, T x);void push_back(T x);    // 在末尾插入元素 void pop_back();        // 在末尾删除元素 void output() const; };template<typename T>
doubleChain<T>::doubleChain(int capacity)
{if(capacity<1){cout << "The capacity is invalid" << endl;return;}firstNode = NULL;lastNode = NULL;listSize = 0;
}template<typename T>
doubleChain<T>::doubleChain(const doubleChain<T>& d_chain)
{listSize = d_chain.listSize;if(listSize==0)     // 复制空链表 {firstNode = NULL;lastNode = NULL;}else     // 非空链表 {doubleChainNode<T>* sourceNode = d_chain.firstNode;firstNode = new doubleChainNode<T>(sourceNode->element, NULL, NULL);doubleChainNode<T>* targetNode = firstNode; while(sourceNode != NULL){sourceNode = sourceNode->next;   // sourcexuNode向后移动 targetNode->next = new doubleChainNode<T>(sourceNode->element, targetNode, NULL);targetNode = targetNode->next;lastNode = targetNode;}//lastNode = targetNode;   }
} template<typename T>
doubleChain<T>::~doubleChain()    // 析构函数
{doubleChainNode<T>* currentNode = firstNode;while(currentNode != NULL){firstNode = currentNode->next;delete currentNode;currentNode = firstNode;} //delete currentNode;//listSize = 0;
}template<typename T>
bool doubleChain<T>::empty() const
{return listSize==0;
}template<typename T>
int doubleChain<T>::size() const
{return listSize;
}template<typename T>
T& doubleChain<T>::get(int index) const
{// 判断index的合法性// 双向链表的索引 if(index<listSize/2)   // 从前向后找 {doubleChainNode<T>* currentNode = firstNode;int cnt=0;while(currentNode != NULL){if(cnt == index){return currentNode->element;}currentNode = currentNode->next;cnt++; }} else                  // 从后向前找 {doubleChainNode<T>* currentNode = lastNode;int cnt = 0;while(currentNode != NULL){if(cnt == listSize-index-1){return currentNode->element;}currentNode = currentNode->previous;cnt++;}}
}template<typename T>
int doubleChain<T>::indexOf(T x) const
{doubleChainNode<T>* currentNode = firstNode;int cnt = 0;while(currentNode != NULL)   // 从头找到尾,包含最后一个元素 {if(currentNode->element == x){return cnt;}currentNode = currentNode->next;cnt++;}return -1;
} template<typename T>
void doubleChain<T>::insert(int index, T x)
{if(index==0)   // 在链表的头部插入元素{if(listSize==0){//doubleChainNode<T>* tempNode = firstNode->next;firstNode = new doubleChainNode<T>(x, NULL, NULL);  // 第一个节点 lastNode = firstNode; }else{firstNode = new doubleChainNode<T>(x, NULL, firstNode);}} else if(index == listSize) // 最后一个位置 {//oubleChainNode<T>* tempNode = lastNode->previous;//lastNode = new doubleChainNode<T>(x, lastNode, NULL);lastNode->next = new doubleChainNode<T>(x, lastNode, NULL);lastNode = lastNode->next;    }else{doubleChainNode<T>* currentNode = firstNode;for(int i=0; i<index; i++){currentNode = currentNode->next;}// currentNode指向第index个节点doubleChainNode<T>* former = currentNode->previous;former->next = new doubleChainNode<T>(x, former, currentNode); }listSize++;
}template<typename T>
void doubleChain<T>::erase(int index)     // 测试通过
{// 检查index的合法性if(index == 0)   // 删除首个元素 {doubleChainNode<T>* currentNode = firstNode;firstNode = firstNode->next;firstNode->previous = NULL;delete currentNode; } else if(index==listSize-1){doubleChainNode<T>* currentNode = lastNode;lastNode = lastNode->previous;lastNode->next = NULL;delete currentNode;}else{if(index<=listSize/2)     // 从左至右查找 {doubleChainNode<T>* currentNode = firstNode;// int cnt=0;for(int i=0; i<index; i++){currentNode = currentNode->next;}// currentNode指向第index个节点doubleChainNode<T>* former = currentNode->previous;doubleChainNode<T>* latter = currentNode->next;former->next = latter;latter->previous = former;delete currentNode; } else{doubleChainNode<T>* currentNode = lastNode;// int cnt=0;for(int i=0; i<listSize-index-1; i++){currentNode = currentNode->previous;}// currentNode指向第index个节点doubleChainNode<T>* former = currentNode->previous;doubleChainNode<T>* latter = currentNode->next;former->next = latter;latter->previous = former;delete currentNode;  }}listSize--;
} template<typename T>
void doubleChain<T>::clear()   // 清除链表所有元素
{doubleChainNode<T>* currentNode = firstNode;while(currentNode != NULL){firstNode = currentNode->next;delete currentNode;currentNode = firstNode;}listSize = 0;firstNode = NULL;lastNode = NULL;
}template<typename T>
void doubleChain<T>::push_back(T x)   // 链表的右端插入一个元素
{if(listSize==0)   // 空链表 {firstNode = new doubleChainNode<T>(x, NULL, NULL);lastNode = firstNode;listSize++;}else       // 非空链表 {lastNode->next = new doubleChainNode<T>(x, lastNode, NULL);lastNode = lastNode->next;listSize++;}
} template<typename T>
void doubleChain<T>::pop_back()    // 删除链表最右端的元素
{if(listSize==1)    // 链表中仅有一个元素   {delete firstNode;firstNode = NULL;lastNode = NULL;listSize = 0;} else               // 大于一个元素 {doubleChainNode<T>* currentNode = lastNode;lastNode = lastNode->previous;lastNode->next = NULL;delete currentNode;listSize--;}
}template<typename T>
void doubleChain<T>::output() const   // 输出函数
{doubleChainNode<T>* currentNode = firstNode;for(int i=0; i<listSize; i++){cout << currentNode->element << "  ";if((i+1)%10==0){//cout << endl;}currentNode = currentNode->next;}cout << endl;
}#endif

双向链表的测试:

#include <iostream>
#include <string>
#include <time.h>
#include "E:\back_up\code\c_plus_code\chain\external_file\linearlist.h"
#include "E:\back_up\code\c_plus_code\chain\external_file\arraylist.h"
#include "E:\back_up\code\c_plus_code\chain\external_file\chain.h"
#include "E:\back_up\code\c_plus_code\chain\external_file\circularlist.h"    // 循环链表
#include "E:\back_up\code\c_plus_code\chain\external_file\doublechain.h"     // 双向链表 using namespace std;// 实现友元函数int main(int argc, char *argv[])
{doubleChain<double> d_chain1;// 测试insert函数:cout << "--------------Insert test----------" << endl;for(int i=0; i<10; i++){d_chain1.insert(i, i+1);} d_chain1.output();d_chain1.insert(2, 1.1); d_chain1.output(); d_chain1.insert(7, 2.7);d_chain1.output(); cout << "----------------------------------" << endl;cout << "--------------erase test----------" << endl;cout << "The list size is " << d_chain1.size() << endl; d_chain1.erase(4);d_chain1.output();cout << "-----------------------------------" << endl;cout << "---------------index test----------------" << endl;double find_m = 3;cout << "The index of " << find_m << " is " << d_chain1.indexOf(find_m) << endl;double find_n = 8;cout << "The index of " << find_n << " is " << d_chain1.indexOf(find_n) << endl;int index_test = 3;cout << "The index " << index_test << " is " << d_chain1.get(index_test) << endl;index_test = 5;cout << "The index " << index_test << " is " << d_chain1.get(index_test) << endl;cout << "-------------push_pop_back---------------------" << endl;d_chain1.push_back(5.20);d_chain1.output();d_chain1.pop_back();d_chain1.output();cout << "-----------------------------------" << endl;cout << "Clearing the list....." << endl;d_chain1.clear();cout << "The list is empty? " << d_chain1.empty() << endl;cout << "------Push_back and pop_back an element----------" << endl;d_chain1.push_back(5.20);d_chain1.output();d_chain1.pop_back();d_chain1.output();return 0;
}

测试结果:

拷贝构造函数的测试:

#include <iostream>
#include <string>
#include <time.h>
#include "E:\back_up\code\c_plus_code\chain\external_file\linearlist.h"
#include "E:\back_up\code\c_plus_code\chain\external_file\arraylist.h"
#include "E:\back_up\code\c_plus_code\chain\external_file\chain.h"
#include "E:\back_up\code\c_plus_code\chain\external_file\circularlist.h"    // 循环链表
#include "E:\back_up\code\c_plus_code\chain\external_file\doublechain.h"     // 双向链表 using namespace std;// 实现友元函数int main(int argc, char *argv[])
{doubleChain<double> d_chain1;// 测试insert函数:cout << "--------------Insert test----------" << endl;for(int i=0; i<10; i++){d_chain1.insert(i, i+1);} d_chain1.output();cout << "---------------Copy constructor test---------------"<< endl; doubleChain<double> d_chain2;d_chain2 = d_chain1;d_chain2.output();cout << "--------------Insert test----------" << endl;d_chain2.insert(2, 1.1); d_chain2.output(); d_chain2.insert(7, 2.7);d_chain2.output(); cout << "----------------------------------" << endl;cout << "--------------erase test----------" << endl;cout << "The list size is " << d_chain2.size() << endl; d_chain2.erase(4);d_chain2.output();cout << "-----------------------------------" << endl;cout << "---------------index test----------------" << endl;double find_m = 3;cout << "The index of " << find_m << " is " << d_chain2.indexOf(find_m) << endl;double find_n = 8;cout << "The index of " << find_n << " is " << d_chain2.indexOf(find_n) << endl;int index_test = 3;cout << "The index " << index_test << " is " << d_chain2.get(index_test) << endl;index_test = 8;cout << "The index " << index_test << " is " << d_chain2.get(index_test) << endl;cout << "-------------push_pop_back---------------------" << endl;d_chain2.push_back(5.20);d_chain2.output();d_chain2.pop_back();d_chain2.output();cout << "Clearing the list...." << endl;d_chain2.clear();cout << "The list is empty? " << d_chain2.empty() << endl;return 0;
}

测试结果:

----------------------------------------------------------end------------------------------------------------------------------

数据结构与算法笔记(四) 循环链表和双向链表相关推荐

  1. 数据结构与算法笔记(十五)—— 散列(哈希表)

    一.前沿 1.1.直接寻址表 当关键字的全域U比较小时,直接寻址是一种简单而有效的技术.假设某应用要用到一个动态集合,其中每个元素都有一个取自全域U={0,1,-,m-1)的关键字,此处m是一个不很大 ...

  2. 数据结构与算法笔记(青岛大学王卓老师视频)

    写在前面的话: 因为在学习数据结构之前,学习过一年的算法,所以有一些基础,一些我觉得 没必要的代码或知识就没写上,记得多是一些知识点,写的可能对于别人来说 很难接受,望谅解.我学习算法是在Acwing ...

  3. 数据结构与算法笔记(十六)—— 二叉搜索树

    一.二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: 若左子树不为空,则左子树上所有节点的 ...

  4. 数据结构和算法(四)之链表结构

    数据结构和算法(四)之链表结构 一. 认识链表 链表和数组一样,可以用来存储一系列的元素,但是链表和数组的实现机制完全不同. 这一章中,我们就来学习一下另外一种非常常见的用于存储数据的线性结构:链表! ...

  5. JS数据结构与算法 笔记

    JS数据结构与算法笔记 前言:不定时更新说明 1. 栈(Stack) 1.1 基于数组实现栈 1.2 基于对象实现栈 1.3 基于链表实现栈 1.4 栈的简单应用 1.4.1 字符串中的括号匹配问题 ...

  6. 数据结构与算法笔记(王卓网课+教材+大话数据结构)

    数据结构与算法笔记(王卓网课+教材+大话数据结构) ##最新整理!!! 顺序存储结构的线性表P10-P21 顺序线性表的代码实现 链式线性表笔记 串笔记 绪论.算法(P1-P9)1.4数据起源结构 数 ...

  7. 数据结构与算法笔记 - 绪论

    数据结构与算法笔记 - 绪论 1. 什么是计算 2. 评判DSA优劣的参照(直尺) 3. 度量DSA性能的尺度(刻度) 4. DSA的性能度量的方法 5. DSA性能的设计及其优化 x1. 理论模型与 ...

  8. Python数据结构与算法(2.4)——双向链表

    Python数据结构与算法(2.4)--双向链表 0. 学习目标 1. 双向链表简介 1.1 双向链表介绍 1.2 双向链表结点类 1.3 双向链表优缺点 2. 双向链表实现 2.1 双向链表的初始化 ...

  9. 04_JavaScript数据结构与算法(四)队列

    JavaScript 数据结构与算法(四)队列 认识队列 队列(Queue)是一种运算受限的线性表,特点:先进先出.(FIFO:First In First Out) 受限之处: 只允许在表的前端(f ...

  10. 算法笔记四 排队买票

    算法笔记四 排队买票 题干 思路 解法一 解法二(转载自https://blog.dotcpp.com/a/64305) 解法三 递归 代码实现 解法二 卡特兰数 解法三 递归 题干 描述 有M个小孩 ...

最新文章

  1. [小改进]Blog页面导航调整
  2. 阿里P9架构师分享:通俗易懂Redis原理,都是你没看过的
  3. python如何绘制曲线图_python怎么画曲线图
  4. 内存泄漏的常见应用领域
  5. A股收盘:深证区块链50指数跌1.75%,*ST群兴、亚联发展涨停
  6. flag - 待浏览学习网站
  7. 自定义类加载器的父类为什么是AppClassLoader?
  8. java tomcat热部署_intellij idea tomcat热部署配置教程
  9. 天池大数据竞赛——UI特征统计
  10. 微信小程序样式拼接 类名三元运算 以及条件拼接
  11. Python探路-多重继承
  12. 一些网址备忘 (在线剪辑音频、在线工具箱、全网音乐下载)
  13. 有向图的拓扑排序算法JAVA实现。
  14. 28 JS基础之--String包装数据类型方法总结
  15. 电脑录制视频的方法很简单 轻松录制完美视频
  16. SQL数据库修复例子
  17. 【网络工程师配置篇】华为RIP路由基础配置续篇——重分发
  18. 不可错过的javascript迷你库 1
  19. 潭州全栈web前端:从原生javescript到jQuery交互实战视频课程
  20. 医院WLAN无线认证解决方案

热门文章

  1. Sentinel流控规则_流控等待_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0037
  2. Netty工作笔记0043---单Reactor多线程模式
  3. 架构设计工作笔记003---中台概念_业务中台_数据中台_技术中台
  4. 关于git clone 下载apex 过程中,缺少libssl.so.1.0.0的问题
  5. 彩色图+车牌颜色测试结果分析
  6. 杭电4502吉哥系列故事——临时工计划
  7. 根据控件ID得到句柄
  8. 编程之美——数字哑谜
  9. 3d激光雷达开发(旋转和位移)
  10. 随想录(lua源码学习)