之前也写过一篇C语言实现简单的双向循环链表,现在使用C++再来扩展一下内容。除了节点的插入、删除,还增加了一些链表的其他操作,包括节点修改、节点替换、节点查找、值查找、值排序等等。内容还是挺丰富的,废话不多说,上代码吧,有问题的欢迎提出来
顺便,一些简单的函数就在类中实现了
class node{
public:
node *prev;
node *next;
uint32_t data;
};
typedef class node Node,*pNode;
class list:public node{
public:
list(){ //构造一个链表头
head = new Node;
list_len = 0;
head->prev = head;
head->next = head;
list_len++;
cout << "list Head:" << head << endl;
}
~list(){
head = NULL;
delete head;
}
//add and delete
pNode list_addhead(uint32_t dat); //头插
pNode list_addtail(uint32_t dat); //尾插
pNode list_add(uint16_t coord, uint32_t dat); //按位置插入
pNode list_delhead(void); //头删
pNode list_deltail(void); //尾删
pNode list_del(uint16_t coord); //按位置删除
pNode list_delnode(pNode node); //按节点地址删除
//find and change
pNode list_sortval(void); //值排序,交换值,不改变节点
pNode list_sortnode(void); //值排序,直接交换节点
pNode list_findval(uint32_t dat); //值查找
uint32_t list_findcursor(uint16_t cnt); //位置查找
pNode list_changeval(uint32_t src_dat, uint32_t des_dat){ //修改值
pNode tmp = NULL;
tmp = list_findval(src_dat);
if(tmp != head){ //find effective value
tmp->data = des_dat;
}
return head;
}
pNode list_changecursorval(uint16_t cnt, uint32_t des_dat){ //修改特定位置的值
if(cnt >= get_list_len()){
cout << "param error!!!" << endl;
return 0;
}
pNode tmp = head;
while(cnt--){
tmp = tmp->next;
}
tmp->data = des_dat;
return head;
}
pNode list_getnode(uint16_t cnt){ //获取节点位置
if(cnt == 0 || cnt >= get_list_len()){
cout << "param error!!!" << endl;
return 0;
}
cout << "cnt: " << cnt <<"\t";
pNode tmp = head;
while(cnt--){
tmp = tmp->next;
}
return tmp;
}
pNode list_changenode(pNode src_node, pNode des_node); //交换节点
uint32_t get_list_len(void){ //获取链表长度
return list_len;
}
pNode list_clear(void){ //清除链表
pNode cursor = head->next;
while(cursor != head){
head->next = cursor->next;
cursor->next->prev = head;
list_len--;
cursor = cursor->next;
delete(cursor);
}
return head;
}
void list_print(void){ //链表打印
if(NULL == head){
cout << "head point empty!!!" << endl;
return;
}
if(head == head->next){
cout << "List empty" << endl;
return;
}
pNode tmp = head->next;
while(tmp != head){
cout << "P:" << tmp << "\tData:" << tmp->data+0 << endl;
tmp = tmp->next;
}
}
protected:
private:
pNode head = NULL;
uint16_t list_len;
};
pNode list::list_addhead(uint32_t dat){
if(NULL == head) list();
pNode tmp = new Node;
if(tmp == head) tmp = new Node;
list_len++;
tmp->next = head->next;
tmp->prev = head;
head->next->prev = tmp;
head->next = tmp;
tmp->data = dat;
return head;
}
pNode list::list_addtail(uint32_t dat){
if(NULL == head) list();
pNode tmp = new Node;
list_len++;
tmp->prev = head->prev;
tmp->next = head;
head->prev->next = tmp;
head->prev = tmp;
tmp->data = dat;
return head;
}
pNode list::list_add(uint16_t coord, uint32_t dat){
if(NULL == head) list();
pNode tmp = new Node;
pNode cursor = head->next;
list_len++;
while(coord--){
cursor = cursor->next;
}
tmp->prev = cursor->prev;
tmp->next = cursor;
cursor->prev->next = tmp;
cursor->prev = tmp;
tmp->data = dat;
return head;
}
pNode list::list_delhead(void){
if((NULL==head) || (head->next==head)){
cout << "List is empty" << endl;
return head;
}
pNode tmp = head->next;
head->next = tmp->next;
tmp->next->prev = head;
list_len--;
delete tmp;
}
pNode list::list_deltail(void){
if((NULL==head) || (head->next==head)){
cout << "List is empty" << endl;
return head;
}
pNode tmp = head->prev;
head->prev = tmp->prev;
tmp->prev->next = head;
list_len--;
delete tmp;
}
pNode list::list_del(uint16_t coord){
if((NULL==head) || (head->next==head)){
cout << "List is empty" << endl;
return head;
}
if(coord >= get_list_len()){
cout << "param error!!!" << endl;
return head;
}
pNode cursor = head->next;
pNode tmp = NULL;
while(coord--){
cursor = cursor->next;
}
tmp = cursor;
cursor->prev->next = cursor->next;
cursor->next->prev = cursor->prev;
list_len--;
delete cursor;
}
pNode list::list_delnode(pNode node){
pNode tmp = head->next;
while(tmp != head){
if(node == tmp){
node->prev->next = node->next;
node->next->prev = node->prev;
list_len--;
delete node;
cout << "delete Node success" << endl;
return head;
}
tmp = tmp->next;
}
cout << "Not find this Node" << endl;
return head;
}
链表的值查找:检索链表是是否有该值,有的话返回该节点的位置;
链表的位置查找:查找链表的第n个节点的值是多少,并返回该值;
pNode list::list_findval(uint32_t dat){
pNode tmp = head->next;
while(tmp != head){
if(dat == tmp->data){
cout << "find dat:" << dat << "\taddr:" << tmp << endl;
return tmp;
}
tmp = tmp->next;
}
cout << "Not find dat" << endl;
return head;
}
uint32_t list::list_findcursor(uint16_t cnt){
if(cnt >= get_list_len()){
cout << "param error!!!" << endl;
return 0;
}
pNode tmp = head;
while(cnt--){
tmp = tmp->next;
}
return tmp->data;
}
先判断替换的两个节点是否在该链表中,是否为同一个节点;
判断两个节点是否相邻;
节点处理咯
pNode list::list_changenode(pNode src_node, pNode des_node){
pNode tmp = head->next;
uint8_t flag = 0;
cout << "\n\nsrc_node:" << src_node << "\tdes_node:" << des_node << endl;
if(src_node == des_node){
cout << "desNode equel desNode" << endl;
return head;
}
while(tmp != head){
if((tmp==src_node) || (tmp==des_node)){
flag++;
}
tmp = tmp->next;
}
if(2 != flag){
cout << "pNode param error" << endl;
return head;
}
if(src_node->next == des_node){
src_node->prev->next = src_node->next;
src_node->next->prev = src_node->prev;
src_node->next = des_node->next;
src_node->prev = des_node;
des_node->next->prev = src_node;
des_node->next = src_node;
}else if(des_node->next == src_node){
des_node->prev->next = des_node->next;
des_node->next->prev = des_node->prev;
des_node->next = src_node->next;
des_node->prev = src_node;
src_node->next->prev = des_node;
src_node->next = des_node;
}else{
pNode pSrc = src_node->prev;
pNode pDes = des_node->prev;
src_node->prev->next = src_node->next;
src_node->next->prev = src_node->prev;
src_node->next = pDes->next;
src_node->prev = pDes;
pDes->next->prev = src_node;
pDes->next = src_node;
des_node->prev->next = des_node->next;
des_node->next->prev = des_node->prev;
des_node->next = pSrc->next;
des_node->prev = pSrc;
pSrc->next->prev = des_node;
pSrc->next = des_node;
}
return head;
}
一、根据链表中的数据进行升序排序,只交换值,节点不做更改;
二、根据链表中的数据进行升序排序,直接交换节点的位置。
pNode list::list_sortval(void){
uint16_t len = get_list_len();
for(uint16_t i=0;i list_findcursor(j+1)){
uint32_t tmp = list_findcursor(j+1);
list_changecursorval(j+1, list_findcursor(j));
list_changecursorval(j, tmp);
}
}
}
return head;
}
pNode list::list_sortnode(void){
uint16_t len = get_list_len();
for(uint16_t i=0;i list_findcursor(j+1)){
list_changenode(list_getnode(j), list_getnode(j+1));
}
}
}
return head;
}
该链表的功能函数较多,整体测试篇幅有限,所以进行功能性分块测试,有兴趣的也可以自行综合测试。
int main(void){
list L;
uint16_t cnt = 0;
uint16_t cursor = 0;
uint32_t tmp = 0;
cout << "Insert Node from head" << endl;
cout << "How many Node need to insert" << endl;
cin >> cnt;
for(uint16_t i=0;i> tmp;
L.list_addhead(tmp);
}
L.list_print();
L.get_list_len();
cout << "\nInsert Node from tail" << endl;
cout << "How many Node need to insert" << endl;
cin >> cnt;
for(uint16_t i=0;i> tmp;
L.list_addtail(tmp);
}
L.list_print();
L.get_list_len();
}
int main(void){
list L;
uint16_t cnt = 0;
uint16_t cursor = 0;
uint32_t tmp = 0;
cout << "Insert Node from head" << endl;
cout << "How many Node need to insert" << endl;
cin >> cnt;
for(uint16_t i=0;i> tmp;
L.list_addhead(tmp);
}
L.list_print();
L.get_list_len();
cout << "\ndelete Node from head" << endl;
cout << "How many Node need to delete" << endl;
cin >> cnt;
for(uint16_t i=0;i> cnt;
for(uint16_t i=0;i> cnt;
for(uint16_t i=0;i> cursor;
L.list_del(cursor);
}
L.list_print();
L.get_list_len();
}
int main(void){
list L;
uint16_t cnt = 0;
uint16_t cursor = 0;
uint32_t tmp = 0;
cout << "Insert Node from head" << endl;
cout << "How many Node need to insert" << endl;
cin >> cnt;
for(uint16_t i=0;i> tmp;
L.list_addhead(tmp);
}
L.list_print();
L.get_list_len();
cout << "\nfind function test" << "\nEnter the value to look for" << endl;
cin >> tmp;
L.list_findval(tmp);
cin >> tmp;
L.list_findval(tmp);
cout << "\nEnter the cursor to look for" << endl;
cin >> tmp;
cout << "Get value:" << L.list_findcursor(tmp) << endl;
cin >> tmp;
cout << "Get value:" << L.list_findcursor(tmp) << endl;
cout << "\nGet Node" << endl;
cin >> cursor;
L.list_getnode(cursor);
cin >> cursor;
L.list_getnode(cursor);
}
int main(void){
list L;
uint16_t cnt = 0;
uint16_t cursor = 0;
uint32_t tmp = 0;
uint32_t val = 0;
cout << "Insert Node from head" << endl;
cout << "How many Node need to insert" << endl;
cin >> cnt;
for(uint16_t i=0;i> tmp;
L.list_addhead(tmp);
}
L.list_print();
L.get_list_len();
cout << "\nchange function test" << "\nEnter the value to replace" << endl;
cin >> tmp >> val;
L.list_changeval(tmp, val);
L.list_print();
cin >> tmp >> val;
L.list_changeval(tmp, val);
L.list_print();
cout << "\nEnter the value and coord to replace" << endl;
cin >> cursor >> tmp;
L.list_changecursorval(cursor, tmp);
L.list_print();
cin >> cursor >> tmp;
L.list_changecursorval(cursor, tmp);
L.list_print();
cout << "\nChange Node" << endl;
cin >> cnt >> cursor;
L.list_changenode(L.list_getnode(cnt), L.list_getnode(cursor));
L.list_print();
cin >> cnt >> cursor;
L.list_changenode(L.list_getnode(cnt), L.list_getnode(cursor));
L.list_print();
}
int main(void){
list L;
uint16_t cnt = 0;
uint16_t cursor = 0;
uint32_t tmp = 0;
uint32_t val = 0;
cout << "Insert Node from head" << endl;
cout << "How many Node need to insert" << endl;
cin >> cnt;
for(uint16_t i=0;i> tmp;
L.list_addhead(tmp);
}
L.list_print();
L.get_list_len();
cout << "\nSort the list, Just sort value" << endl;
L.list_sortval();
L.list_print();
L.list_clear();
cout << "\nHow many Node need to insert" << endl;
cin >> cnt;
for(uint16_t i=0;i> tmp;
L.list_addhead(tmp);
}
L.list_print();
L.get_list_len();
cout << "\nSort the list" << endl;
L.list_sortnode();
L.list_print();
}
链表的增删改查排序等操作就完了
结合例程,大家可以试着用链表实现栈、队列、环形缓冲区、拆分链表、接合链表、链表的多种排序、判断链表是否有环、哈希链表等更复杂的数据结构和算法咯
== 略 略略略==