赞
踩
这里头节点是不存储数据的,且单向链表的操作,双向链表都可以做到,这里讲一下双向链表的特点。
如果想看一些基础的增删改查工作,直接查看单链表即可
废话不多说,直接上干货
//定义链表
typedef struct Node{
int data;//存放数据
Node* pre; //指向上一个节点
Node* next;//指向下一个节点
Node(): data(0),pre(NULL),next(NULL){};
Node(int x, Node* node): data(x),pre(node),next(NULL){};
Node(int x, Node* node, Node* node2): data(x),pre(node),next(node2){};
}*ListNode;
上述定义了一个双向链表的节点,包含数据,前驱指针和后继指针。
这里采用了三种构造函数,包括有参的重载。
因为这里我们写了链表的一个有参构造,这样初始化链表就变得非常简单
template<typename T> void CreateList(ListNode &link_list, T arr, int len){ Node* p = link_list; for(int i=0; i<len; i++){ p->next = new Node(arr[i], p); //每一步都设置前驱节点 p = p->next; } } void ShowList(const ListNode &link_list){ Node* p = link_list->next; if(NULL == p) return; while(NULL != p->next){ cout << p->data << "\t"; p = p->next; } cout<<p->data << endl; } int main(void){ ListNode link_list = new Node(); vector<int> a = {1,2,3,4,5}; CreateList(link_list, a, a.size()); Node *p = link_list->next->next; cout<<p->pre->data<<endl; ShowList(link_list); system("pause"); return 0; }
直接调用有参构造就可以了。
增删改查操作,单链表能做的,双向链表也能做,不过有一些区别
//插入尾部节点 void InsertRear(ListNode &link_list, int val){ Node *p = link_list; while(NULL != p->next){ p = p->next; } p->next = new Node(val, p); } //插入中间节点 void InsertInside(ListNode &link_list,int index, int val){ int count = 0; Node *p = link_list; while(NULL != p->next){ if(count == index){ Node *temp = new Node(val, p); //新节点的前驱指针指向p temp->next = p->next; //新节点的后继指针指向后一个节点 p->next->pre = temp; //后继节点的前驱指针指向新节点 p->next = temp; //前驱节点的后继指针指向新节点 return; } p = p->next; count++; } cout<<"插入失败"<<endl; }
void RemoveRear(ListNode &link_list){ Node *p = link_list->next; if(NULL == p){ cout << "链表为空" << endl; return; }else if(NULL == p->next){ delete p; link_list->next = NULL; } while(NULL != p->next->next){ p = p->next; } delete p->next; p->next = NULL; } void RemoveInside(ListNode &link_list, int index){ Node *p = link_list; if(NULL == p->next){ cout << "链表为空" << endl; return; } int count = 0; while(NULL != p->next->next){ if(count == index){ Node* temp = p->next->next; //得到后继节点 temp->pre = p; //修改后继节点的前驱指针 delete p->next; //删除节点 p->next = temp; //修改前驱节点的后继指针 return; } p = p->next; count++; } cout << "index 超出索引" << endl; }
双向链表麻烦的地方就在于指针的指向操纵要更加的复杂一点,但是同样灵活性也更加的好一些。
Node* FindNode(const ListNode &link_list, int val){
Node *p = link_list->next;
while(NULL != p){
if(p->data == val) return p;
p = p->next;
}
return NULL;
}
这个和单链表是一样的
void ChangeNode(ListNode &link_list,int index, int val){ int count = 0; Node *p = link_list->next; if(NULL == p){ cout << "链表为空" << endl; return; } while(NULL != p->next){ if(count == index){ p->data = val; return; } p = p->next; count++; } cout<<"修改失败"<<endl; }
具体的问题需要具体的分析,目前还没遇到过什么问题使用双链表才是妙手的情况,所以这里暂时就介绍基础的操作。
老规矩,有用,希望能送上你的二连,感谢!
全部代码
#include<iostream> #include<cstdlib> #include<cstring> #include<string> #include<vector> using namespace std; //定义链表 typedef struct Node{ int data;//存放数据 Node* pre; //指向上一个节点 Node* next;//指向下一个节点 Node(): data(0),pre(NULL),next(NULL){}; Node(int x, Node* node): data(x),pre(node),next(NULL){}; Node(int x, Node* node, Node* node2): data(x),pre(node),next(node2){}; }*ListNode; template<typename T> void CreateList(ListNode &link_list, T arr, int len){ Node* p = link_list; for(int i=0; i<len; i++){ p->next = new Node(arr[i], p); p = p->next; } } void ShowList(const ListNode &link_list){ Node* p = link_list->next; if(NULL == p) return; while(NULL != p->next){ cout << p->data << "\t"; p = p->next; } cout<<p->data << endl; } Node* FindNode(const ListNode &link_list, int val){ Node *p = link_list->next; while(NULL != p){ if(p->data == val) return p; p = p->next; } return NULL; } void InsertRear(ListNode &link_list, int val){ Node *p = link_list; while(NULL != p->next){ p = p->next; } p->next = new Node(val, p); } void InsertInside(ListNode &link_list,int index, int val){ int count = 0; Node *p = link_list; while(NULL != p->next){ if(count == index){ Node *temp = new Node(val, p); //新节点的前驱指针指向p temp->next = p->next; //新节点的后继指针指向后一个节点 p->next->pre = temp; //后继节点的前驱指针指向新节点 p->next = temp; //前驱节点的后继指针指向新节点 return; } p = p->next; count++; } cout<<"插入失败"<<endl; } void ChangeNode(ListNode &link_list,int index, int val){ int count = 0; Node *p = link_list->next; if(NULL == p){ cout << "链表为空" << endl; return; } while(NULL != p->next){ if(count == index){ p->data = val; return; } p = p->next; count++; } cout<<"修改失败"<<endl; } void RemoveRear(ListNode &link_list){ Node *p = link_list->next; if(NULL == p){ cout << "链表为空" << endl; return; }else if(NULL == p->next){ delete p; link_list->next = NULL; } while(NULL != p->next->next){ p = p->next; } delete p->next; p->next = NULL; } void RemoveInside(ListNode &link_list, int index){ Node *p = link_list; if(NULL == p->next){ cout << "链表为空" << endl; return; } int count = 0; while(NULL != p->next->next){ if(count == index){ Node* temp = p->next->next; //得到后继节点 temp->pre = p; //修改后继节点的前驱指针 delete p->next; //删除节点 p->next = temp; //修改前驱节点的后继指针 return; } p = p->next; count++; } cout << "index 超出索引" << endl; } int main(void){ ListNode link_list = new Node(); vector<int> a = {1,2,3,4,5}; CreateList(link_list, a, a.size()); Node *p = link_list->next->next; cout<<p->pre->data<<endl; ShowList(link_list); InsertInside(link_list, 0, 100); ShowList(link_list); InsertInside(link_list, 6, 100); ShowList(link_list); InsertRear(link_list, 100); ShowList(link_list); InsertInside(link_list, 2, 100); ShowList(link_list); RemoveRear(link_list); ShowList(link_list); RemoveInside(link_list, 6); ShowList(link_list); Node *temp = FindNode(link_list, 100); cout << temp->data << endl; ChangeNode(link_list, 0, 1000); ShowList(link_list); system("pause"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。