#include <iostream>
using namespace std;
class node{
public:
int data;
node *next;
};
class list{
private:
node *head;
node *temp;
public:
list():temp(NULL),head(NULL){}//初始化节点
// ~list(); //析构
node *create_list(); //尾插法创造单链表
node *list_create(); //头插法创建单链表
bool isEmpty(); //判断链表是否为空
int length_list(); //求链表的长度
int getData(); //查找数据(按值查找位置)
int getData2(); //查找数据(按位置查找值)
node *insert_list(); //插入数据
node *delete_list(); //删除数据(根据数据删除)
node *delete_list2(); //删除数据(根据位置删除)
node *reverse_list(); //逆置单链表
node *traversal(); //遍历线性表
node *splice(node *l1,node *l2); //新增两个有序链表拼接成新有序链表
};
//尾插法创建单链表
node *list::create_list()
{
int x=0;
node *temp = NULL;
while(x != -1)
{
cin>>x;
if(x == -1)
{
break;
}
p = new node;
p->data = x;
if(head == NULL && x != -1)
{
head = p;
}
else if(head != NULL && x != -1)
{
temp->next = p;
}
temp = p;
}
if(temp != NULL)
{
temp->next = NULL;
}
return head;
}
//判断链表是否为空
bool list::isEmpty()
{
return head->next == NULL;
}
//判断链表长度
int list::length_list()
{
int i = 0; // 计数器
node *p;
p = head;
while(p->next)
{
p = p->next;
i++;
}
return i;
}
//通过数据查找位置
int list::getData()
{
node *p;
p = head->next;
int n,i = 0;
cout<<"请输入你想得到的数据:";
cin>>n; //查找数值为n的数据所在的位置
while(p != NULL)
{
if(p->data == n)
{
cout<<"你所要查找的值的位置为:"<<++i<<endl;
return i;
}
else
{
p = p->next;
i++;
}
}
return i;
}
//通过数据查找位置
int list::getData2()
{
int n,i = 0;
cout<<"请输入你想查找的位置:";
cin>>n;
node *p;
p = head;
do{
p = p->next;
i++;
}while(i != n);
cout<<"你想得到的数据为:"<<p->data<<endl;
return p->data;
}
//插入数据
node *list::insert_list()
{
node *p = head;
temp = new node;
int i; //插入数据的位置
int n; //插入的数据
cout<<"请输入你想插入的数据:";
cin>>n;
cout<<"请输入你想插入数据的位置:";
cin>>i;
temp->data = n;
if(i<1||i>length_list())
{
cout<<"位置不存在!"<<endl;
}
else
{
int m = 1;
while(m != i)
{
m++;
p = p->next;
}
temp->next = p->next; //与头插法类似
p->next = temp;
traversal();
}
return head;
}
//通过数据删除数据
node *list::delete_list()
{
int x;
node *p = head->next;
cout<<"请输入你想删除的数据:";
cin>>x;
while(p->data != x)
{
p = p->next;
}
p->data = p->next->data; //此方法无需找到前驱节点,只需要将后一个节点完全复制到前一个节点就可
p->next = p->next->next;
traversal();
return head;
}
//通过位置删除数据
node *list::delete_list2()
{
int i,n = 0;
node *p = head;
cout<<"请输入你想删除的位置:";
cin>>i;
while(n != i)
{
p = p->next;
n++;
}
p->data = p->next->data; //此方法无需找到前驱节点,只需要将后一个节点完全复制到前一个节点就可
p->next = p->next->next;
traversal();
return head;
}
//单链表的逆置
//逆置链表方法有很多种,如:新创建一个链表,然后将原链表数据逆次放入新链表中。但是此方法对内存开销较大,不建议使用
node *list::reverse_list()
{
node *p = new node; //为p申请一个新的节点
temp = new node; //为temp申请一个节点
p = head->next; //令 p 与 head->next 变成同一块节点
temp = p->next; //让 temp 与 p->next 变成同一块节点
head->next = NULL; //由于我们要做到逆置链表,因此可让head->next指向空,可将head看做"new node"类型
while(p != NULL)
{
p->next = head;
if(temp == NULL)
break;
head=p;
p=temp;
temp=temp->next;
}
cout<<head->data<<" "; //这里将最后一个值输出,若不这么做,链表最后一个值无法得到
traversal();
return p;
}
//遍历单链表
node *list::traversal()
{
node *temp = head;
if(temp == NULL)
{
cout<<"NULL"<<endl;
return NULL;
}
cout<<temp->data;
temp = temp->next;
while(temp != NULL)
{
cout<<" "<<temp->data;
temp = temp->next;
}
cout<<endl;
return head;
}
int main()
{
list com; com.create_list();
com.isEmpty();
com.length_list();
com.getData();
com.getData2();
com.insert_list();
com.delete_list2();
com.reverse_list();
return 0;
}