2019《王道数据结构》算法题-单链表C++实现

#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
template<class T>
struct Node{
	T data;
	Node<T>* next;
	Node(Node<T>* ptr = NULL)
	{
		next = ptr;
	}
	Node(const T& item , Node<T>* ptr = NULL)
	{
		data = item;
		next = ptr;
	}
}; 
template<class T>
class LinkList{//单链表 
	public:
		LinkList(){
			head = current =  new Node<T>();
			count = 0;
		}
		/*LinkList(const T& x){
			head = new Node<T>(x);
		}*/
		LinkList(LinkList<T>& L){
			T value;
			count = L.length();
			head = new Node<T>();
			Node<T>* p = head;
			Node<T>* temp = L.getHead()->next;
			for(int i = 0; i < count; i++){
				p->next = new Node<T>(temp->data);
				p = p->next;
				temp = temp->next;
			}
		}
		~LinkList(){
			Node<T>* q;
			while(head->next != NULL){
				q = head->next;
				head->next = q->next;
				delete q; 
				count--;
			}
		}
		int length() const
		{
			return count;
		}
		Node<T>*& getHead()
		{
			return head;
		}
		void setHead(Node<T> *p){
			head = p;
		}
		Node<T>* search(T x){
			Node<T>* temp = head;
			while(temp != NULL){
				if(temp->data == x)
					return temp;
				temp = temp->next;
			}
			return NULL;
		}
		Node<T>* locate(int index){
			if(index > count - 1 || index < -1){
				cerr << "索引越界!" << endl;
				exit(1);
			}
			Node<T>* temp = head->next;
			for(int i = 0; i < index; i++){
				temp = temp->next;
			}
			return temp;
		}
		T get(int index){
			if(index > count - 1 || index < -1){
				cerr << "索引越界!" << endl;
				exit(1);
			}
			Node<T>* temp = head->next;
			for(int i = 0; i < index; i++){
				temp = temp->next;
			}
			return temp->data;
		}
		void set(int index , T x){
			if(index > count - 1 || index < -1){
				cerr << "索引越界!" << endl;
				exit(1);
			}
			Node<T>* temp = head->next;
			for(int i = 0; i < index; i++){
				temp = temp->next;
			}
			temp->data = x;
		}
		bool insert(int index , T x){
			if(index > count || index < -1){
				cerr << "索引越界!" << endl;
				return false;
			}
			Node<T>* temp = head;
			if(index != 0){
				temp = head->next;
				for(int i = 0; i < index-1; i++){
					temp = temp->next;
				}	
			}
			temp->next = new Node<T>(x,temp->next);
			count++;
			return true;
		}
		T remove(int index){
			if(index > count - 1 || index < -1){
				cerr << "索引越界!" << endl;
				exit(1);
			}
			Node<T>* temp = head;
			if(index != 0){
				temp = head->next;
				for(int i = 0; i < index-1; i++){
					temp = temp->next;
				}	
			}
			Node<T>* p = temp->next;
			T x = p->data;
			temp->next = temp->next->next;
			delete p;
			count--;
			return x;
		}
		void print() const
		{
			Node<T>* temp = head->next;
			while(temp != NULL){
				cout << temp->data << " ";
				temp = temp->next;
			}
		}
		bool isEmpty() const
		{
			return count == 0;
		}
		bool add(T x){
			return insert(count,x);
		}
		T operator[](int index){
			return get(index);
		}
		template<class X>
		static void print1(Node<X>* a){
			Node<X>* temp = a;
			while(temp != NULL){
				cout << temp->data << " ";
				temp = temp->next;
			}
		}
		template<class X>
		static void print2(Node<X>* a){
			Node<X>* temp = a->next;
			while(temp != NULL){
				cout << temp->data << " ";
				temp = temp->next;
			}
		}
	private:
		Node<T>* head;
		Node<T>* current;
		int count;
	/*
		**************以下是《王道数据结构》算法题************** 
	*/ 
	public:
		template<class X>
		static void deleteXWithoutHead(Node<X>*& L , X x)
		{//2.3.7.1递归删除不带头结点的单链表L中所有值为x的结点。
			Node<X>* p = NULL;
			if(L->next == NULL)
				return ;
			if(L->data == x){
				p = L;
				L = L->next;
				delete p;
				deleteXWithoutHead(L,x);
			}else{
				deleteXWithoutHead(L->next,x);
			}
		}
		void deleteXWithHead(T x)
		{//2.3.7.2删除所有值为x的结点。 
			Node<T>* p = head;
			Node<T>* temp = NULL;
			while(p->next != NULL){
				if(p->next->data == x){
					temp = p->next;
					p->next = temp->next;
					delete temp;
					count--;
				}else p = p->next;
			}
		}
		void r_print(Node<T>* L)
		{//2.3.7.3带头结点的单链表,从尾到头反向输出每个结点的值。 
			if(L->next != NULL)
				r_print(L->next);
			if(L != head)
				cout << L->data << " ";
			else cout << endl;
		}
		T deleteMin()
		{//2.3.7.4删除带头结点单链表中最小节点。
			if(head->next->next == NULL){
				Node<T>* p = head->next;
				delete p;
				head->next = NULL;
				return -1;
			}
			Node<T>* pre = head;
			Node<T>* min = head->next;
			Node<T>* temp = min->next;
			Node<T>* t_pre = min;
			while(temp != NULL){
				if(temp->data < min->data){
					min = temp;
					pre = t_pre;
				}
				t_pre = t_pre->next;
				temp = temp->next;
			}
			pre->next = min->next;
			T x = min->data;
			delete min;
			count--;
			return x;
		}
		template<class X>
		static void reverse(Node<X>* L,Node<X>* head,Node<X>* first)
		{//2.3.7.5将带头结点的单链表就地逆置。	
			if(L->next->next != NULL)	
				reverse(L->next,head,first);
			else head->next = L->next;
			if(L != first && L != head){
				L->next->next = L;
			}	
			else if(L == first){
				L->next->next = L;
				L->next = NULL;
			}else {
				return ;
			}
		}
		void sort()
		{//2.3.7.6递增排序. 
			Node<T>* pre = NULL;
			Node<T>* min = NULL;
			Node<T>* temp = NULL;
			Node<T>* t_pre = NULL;
			Node<T>* newHead = new Node<T>();
			Node<T>* rear = newHead;
			while(head->next != NULL){
				pre = head;
				min = head->next;
				temp = min->next;
				t_pre = pre->next; 
				for(; temp != NULL; temp = temp->next,t_pre = t_pre->next){
					if(temp->data < min->data){
						pre = t_pre;
						min = temp;
					}
				}
				pre->next = min->next;
				rear->next = min;
				rear = min;
				rear->next = NULL;	
			}
			delete head;
			head = newHead;
		}
		void deleteBetween(int s , int t)
		{//2.3.7.7删除带头结点单链表中值介于s和t之间的节点。 
			if(s > t){
				cout << "参数错误!" << endl;
				return;
			}
			Node<T>* pre = head,*temp = head->next;
			while(temp != NULL){
				if(temp->data >=s && temp->data <=t){
					Node<T>* p = temp;
					temp = temp->next;
					pre->next = temp;
					delete p;
					continue;
				}
				pre = pre->next;
				temp = temp->next;
			}
		}
		template<class X>
		static Node<X>* publicNode(Node<X>* a , Node<X>* b)
		{//2.3.7.8寻找两单链表的公共节点。 
			//先分别遍历a、b求出它们的长度,再令长的链表先遍历|a-b|长度,再同时遍历比较。 
			int aSize = 0 , bSize = 0;
			Node<X>* temp = a;
			while(temp != NULL){
				aSize++;
				temp = temp->next;
			}
			temp = b;
			while(temp != NULL){
				bSize++;
				temp = temp->next;
			}
			Node<X>* p = NULL;
			Node<X>* q = NULL;
			if(aSize > bSize){
				int n = aSize - bSize;
				p = a;
				for(int i = 0; i < n; i++){
					p = p->next;
				}
				q = b;
			}else{
				int n = bSize - aSize;
				q = b;
				for(int i = 0; i < n; i++)
					q = q->next;
				p = a;
			}
			while(p != q && p != NULL){
				p = p->next;
				q = q->next;
			}
			return p;
		}
		void printAscClear()
		{//2.3.7.9按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间。
		 	Node<T>* temp = NULL , *p_temp = NULL , *max = NULL , *p_max = NULL;
		 	while(head->next != NULL){
		 		p_max = head;
		 		max = head->next;
		 		temp = max->next;
		 		p_temp = max;
		 		for(; temp != NULL; temp = temp->next , p_temp = p_temp->next){
		 			if(temp->data > max->data){
		 				max = temp;
		 				p_max = p_temp;
					 }
				 }
				 cout << max->data << " ";
				 p_max->next = max->next;
				 delete max;
				 count--;
			 }
			 //delete head;
		}
		
		Node<T>* resolve()
		{//2.3.7.10将一个带头结点的单链表A分解为两个带头结点的单链表A和B,使得A表中含有原表中序号为奇数的元素,
		//而B表中含有原表中序号为偶数的元素。
		 	Node<T>* b = new Node<T>();
		 	Node<T>* rear = b;
		 	Node<T>* current = head;
		 	while(current != NULL && current->next != NULL){
		 		rear->next = current->next;
		 		current->next = current->next->next;
		 		rear = rear->next;
		 		current = current->next;
		 		rear->next = NULL;
		 		count--;
			 }
			 return b;	
		 }
		 Node<T>*  resolve2()
		 {//2.3.7.11
		 	Node<T>* b = new Node<T>();
		 	Node<T>* temp = NULL;
		 	Node<T>* hc = head;
		 	Node<T>* current = hc->next;
		 	while(current != NULL && current->next != NULL){
		 		temp = b->next;
		 		b->next = current->next;
		 		current->next = current->next->next;
		 		current = current->next;
		 		b->next->next = temp;
				count--; 
			 }
			 return b;
		 	
		 }
		 void deleteRepeat()
		 {//2.3.7.12删除递增有序单链表中重复元素。
		 	Node<T>* pre = head->next; 
		 	Node<T>* temp = pre->next;
		 	while(temp != NULL){
		 		if(temp->data == pre->data){
		 			pre->next = temp->next;
		 			delete temp;
		 			temp = pre->next;
		 			count--;
				 }else{
				 	pre = temp;
				 	temp = temp->next;
				 }
			 }
		 	
		 }
		 template<class X>
		 static Node<X>* merge1(Node<X>* a , Node<X>* b)
		 {//2.3.7.13a、b为两个按元素值递增排序的单链表,将这两个单链表归并为一个按元素值递减排序的单链表,
		 	//用原来两个单链表的结点存放归并后的单链表。 
		 		Node<X>* newHead = new Node<X>();
		 		Node<X>* temp = NULL;
		 		Node<X>* a_current = a->next;
		 		Node<X>* b_current = b->next;
		 		while(a_current != NULL && b_current != NULL){
		 			temp = newHead->next;
		 			if(a_current->data <= b_current->data){
		 				newHead->next = a_current;
		 				a_current = a_current->next;
					 }else{
					 	newHead->next = b_current;
		 				b_current = b_current->next;
					 }
					 newHead->next->next = temp;
				}
				while(a_current != NULL){
				 	temp = newHead->next;
				 	newHead->next = a_current;
		 			a_current = a_current->next;
		 			newHead->next->next = temp;
				}
				while(b_current != NULL){
				 	temp = newHead->next;
				 	newHead->next = b_current;
		 			b_current = b_current->next;
		 			newHead->next->next = temp;
				}
				a->next = NULL;
				b->next = NULL;
				return newHead;
		 }
		 template<class X>
		 static Node<X>* publicElem(Node<X>* a , Node<X>* b)
		 {//2.3.7.14a、b是两个递增有序的带头结点的单链表,设计一个算法从a、b中公共元素产生单链表c,要求不破坏a、b结点。 
		 	Node<X>* c = new Node<X>();
		 	Node<X>* rear = c;
		 	Node<X>* a_current = a->next;
		 	Node<X>* b_current = b->next;
		 	while(a_current != NULL && b_current != NULL){
		 		while((a_current != NULL && b_current != NULL) && (a_current->data != b_current->data)){
		 			while((a_current != NULL && b_current != NULL) && (a_current->data < b_current->data))
		 				a_current = a_current->next;
		 			while((a_current != NULL && b_current != NULL) && (b_current->data < a_current->data))
		 				b_current = b_current->next;
				}
				if(a_current == NULL || b_current == NULL){	
					return c;
				}
				rear->next = new Node<X>(a_current->data,NULL);
				rear = rear->next;
				a_current = a_current->next;
				b_current = b_current->next;
			}
		 	return c;
		 }
		 template<class X>
		 static void intersection(Node<X>* a , Node<X>* b)
		 {//2.3.7.15a、b两个元素递增排列的单链表,求a、b的交集,并存于a中。
		 	Node<X>* pre = a;
		 	Node<X>* a_current = a->next;
		 	Node<X>* b_current = b->next;
		 	Node<X>* temp = NULL;
		 	while(a_current != NULL && b_current !=NULL){
		 		while((a_current != NULL && b_current != NULL) && (a_current->data < b_current->data)){
		 			temp = a_current;
		 			a_current = a_current->next;
		 			pre->next = a_current;
		 			delete temp;
				 }
				if(a_current == NULL || b_current == NULL)
				 	break;
				if(a_current->data == b_current->data){
					while(a_current->data == b_current->data){
						a_current = a_current->next;
				 		pre = pre->next;
					}
				 	b_current = b_current->next;
				}else{
					b_current = b_current->next;
				}	 
			}
		 	while(a_current != NULL){
		 		temp = a_current;
		 		a_current = a_current->next;
		 		pre->next = a_current;
		 		delete temp;
			 }
		 	
		 }
		 template<class X>
		 static bool isSubList1(Node<X>* a , Node<X>* b)
		 {//2.3.7.16判断b是否是a的连续子序列。
		 	Node<X>* a_current = a->next;
		 	Node<X>* b_current = b->next;
		 	Node<X>* temp = NULL;
			while(a_current != NULL){
				while(a_current != NULL && a_current->data != b_current->data)
		 			a_current = a_current->next;
		 		temp = a_current;
		 		while((a_current != NULL && b_current != NULL) && a_current->data == b_current->data){
		 			a_current = a_current->next;
		 			b_current = b_current->next;
				 }
				if(a_current == NULL && b_current != NULL)
					return false;
				if(b_current != NULL){
					b_current = b->next;
					a_current = temp->next;
				}else return true;
			}
			return false;	
		 }
		 template<class X>
		 static int findBackWardK(Node<X>* list , int k)
		 {//2.3.7.21查找链表中倒数第k个位置上的节点,若查找成功,算法输出该结点的data域的值,并返回1,否则返回0; 
		 	Node<X>* temp = list->next;
		 	stack<X> st;
		 	while(temp != NULL){
		 		st.push(temp->data);
		 		temp = temp->next;
			 }
			if(st.size() < k)
				return 0;
			for(int i = 0; i < k-1; i++)
				st.pop();
			cout << st.top() << endl;
			return 1;
		 }
		 template<class X>
		 static Node<X>* findPublicStart(Node<X>* str1 , Node<X>* str2)
		 {//2.3.7.22找出str1和str2所指向两个链表共同后缀的起始位置。
		 	//解题思路跟第8题一样。 
		 	return publicNode(str1,str2);
		 }
		 template<class X>
		 static void deleteAbs(Node<X>* head , int m , int n)
		 {/*2.3.7.23用单链表保存m个整数,且|data|<=n(n为正整数),
		 	设计算法对链表中data绝对值相等的结点,仅保留第一次出现的结点,而删除
			 其余绝对值相等的结点。*/
			bool isExist[n+1] = {false};
			Node<X>* pre = head;
			Node<X>* temp = head->next;
		 	while(temp != NULL){
		 		if(isExist[abs(temp->data)]){
		 			pre->next = temp->next;
		 			delete temp;
		 			temp = pre->next;
		 			continue;
				 }else{
				 	isExist[abs(temp->data)] = true;
				 }
				 pre = pre->next;
				 temp = temp->next;
			 }
		 }
	/*
		***************************END*************************** 
	*/
	/*
		**********************作者QQ632660120 *******************
	*/ 
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值