#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 *******************
*/
};