/* 1. head->next第一个元素, 位置为0
* 2. setPos(-1) return head
* 3. 删除和插入先定位到前一个结点
* 4. 尾结点为临界情况,需要特殊处理 */
#ifndef LNKLIST_H
#define LNKLIST_H
#include <iostream>
using namespace std;
template<class T>
class Node {
public:
T data;
Node<T> *next;
Node(const T info, Node<T> *nextValue = NULL) {
data = info;
next = nextValue;
}
Node(Node<T> *nextValue) {
next = nextValue;
}
};
template<class T>
class lnkList {
private:
Node<T> *head, *tail;
Node<T>* setPos(const int p);
public:
lnkList(int s);
~lnkList();
void print();
void clear();
bool isEmpty();
int length();
bool getValue(const int p, T& value);
bool setValue(const int p, const T value);
bool getPos(int& p, const T value);
bool append(const T value);
bool insert(const int p, const T value);
bool deletee(const int p);
};
/* 1. if para<-1, return false
* 2. if para = -1, return head */
template<class T>
Node<T>* lnkList<T>::setPos(const int i) {
if (i < -1)
return NULL;
if (i == -1)
return head;
Node<T> *p = head->next;
int count = 0;
while (p != NULL && count < i) {
p = p->next;
count++;
}
return p;
}
// defSize????????
template<class T>
lnkList<T>::lnkList(int defSize = 0) {
head = tail = new Node<T>(0,NULL);
cout<<"new empty list!"<<endl;
}
template<class T>
lnkList<T>::~lnkList() {
Node<T> *tmp;
while (head != NULL) {
tmp = head;
head = head->next;
delete tmp;
}
}
template<class T>
void lnkList<T>::print() {
Node<T> *tmp = head->next;
while (tmp != NULL) {
cout<<tmp->data<<" ";
tmp = tmp->next;
}
cout<<endl;
}
template<class T>
void lnkList<T>::clear() {
Node<T> *tmp;
while (head != NULL) {
tmp = head;
head = head->next;
delete tmp;
}
head = tail = new Node<T>(0, NULL);
}
template<class T>
bool lnkList<T>::isEmpty() {
if (head == tail) {
cout<<"list is empty!"<<endl;
return true;
}
return false;
}
template<class T>
int lnkList<T>::length() {
int length = 0;
Node<T> *tmp = head->next;
while (tmp != NULL) {
length++;
tmp = tmp->next;
}
return length;
}
template<class T>
bool lnkList<T>::setValue(const int i, const T value) {
Node<T> *p;
if ((p = setPos(i)) == NULL) {
cout<<"illegal setvalue!"<<endl;
return false;
}
p->data = value;
return true;
}
template<class T>
bool lnkList<T>::getValue(const int i, T& value) {
Node<T> *p;
if ((p = setPos(i)) == NULL) {
cout<<"illegal getvalue!"<<endl;
return false;
}
value = p->data;
return true;
}
template<class T>
bool lnkList<T>::getPos(int &p, const T value) {
Node<T> *q = head->next;
for (int i = 0; i < length(); i++) {
if (q->data == value) {
p = i;
return true;
}
q = q->next;
}
return false;
}
template<class T>
bool lnkList<T>::append(const T value) {
Node<T> *p = new Node<T>(value, NULL);
tail->next = p;
tail = p;
return true;
}
/* 1. if insertion illegal, cann't insert
* 2. p指向插入前一个位置, p = setPos(i-1)
* 3. q为新插入的结点,设置指针:q = p->next, p->next = q
* 4. if p is tail, tail = q */
template<class T>
bool lnkList<T>::insert(const int i, const T value) {
Node<T> *p, *q;
if (i < 0) {
cout<<"insertion illegal!"<<endl;
return false;
}
if ((p = setPos(i-1)) == NULL) {
cout<<"insertion illegal!"<<endl;
return false;
}
q = new Node<T>(value, p->next);
p->next = q;
if (p == tail)
tail = q;
return true;
}
/* 1. if deletion illegal, cann't delete
* 2. p指向删除前一个位置, p = setPos(i-1)
* 3. q为待删除的结点, q = p->next
* 4. if q is tail, tail = p, p->next = NULL, delete q
* 5. p->next = q->next, delete q */
template<class T>
bool lnkList<T>::deletee(const int i) {
Node<T> *p, *q;
if ((p = setPos(i-1)) == NULL || p == tail) {
cout<<"deletion illegal!"<<endl;
return false;
}
q = p->next;
if (q == tail) {
tail = p;
p->next = NULL;
delete q;
}
else if (q != NULL) {
p->next = q->next;
delete q;
}
return true;
}
#endif
#include <iostream>
#include "lnklist.h"
using namespace std;
int
main() {
lnkList<int> list(10);
list.isEmpty();
cout<<"init list 0-4"<<endl;
for (int i = 0; i < 5; i++)
list.append(i);
cout<<"The list is "<<(list.isEmpty()?"empty":"not empty")<<endl;
cout<<list.length()<<endl<<"print the list:"<<endl;
list.print();
cout<<endl;
cout<<"insert(0,5) (3, 5) (7, 5) (9, 5) (-3, 0)"<<endl;
list.insert(0, 5); list.print();
list.insert(3, 5); list.print();
list.insert(7, 5); list.print();
list.insert(9, 5); list.print();
list.insert(-3, 0); list.print();
cout<<endl;
cout<<"setvalue(4, 5) (0, 7) (7, 80) (-4, 5) (33, 5)"<<endl;
list.setValue(4, 5);
list.setValue(0, 7);
list.setValue(7, 80);
list.setValue(-4, 5);
list.setValue(33, 5);
list.print();
cout<<endl;
cout<<"getvalue 0-curLen"<<endl;
int v;
for (int i = 0; i < list.length(); i++) {
list.getValue(i, v);
cout<<v<<" ";
}
cout<<endl;
cout<<"getpos 4, 5"<<endl;
int p;
list.getPos(p, 4);
cout<<p<<" ";
list.getPos(p, 5);
cout<<p<<endl<<endl;
cout<<"delete 0, 3, 5 -3, 9"<<endl;
list.deletee(0);
list.print();
list.deletee(3);
list.deletee(5);
list.print();
list.deletee(-3);
list.deletee(9);
cout<<endl;
list.clear();
list.isEmpty();
return 0;
}