整型单链表,C++实现
成员函数有:
1.构造函数,设置为空链表
2.取给定位置的值
3.判断是否为空链表
4.由给定数组创建链表
5.插入
6.删除
7.打印
PS:结尾附有头插法
***需要注意的点: ***
1.用return一个判断式非常方便(判断是否为空链表那里)
2.插入和删除都是要找到删除元素的上一个,所以会有两种情况
一:找的到上一个
二:找不到上一个,即要插入或删除的位置是开头
第一种情况中要考虑循环次数,比如在3的位置插入(默认从1开始计数),那么指针要指在2的结点,所以要执行p=p->next语句1次(最开始p=head,p在1的位置),由此可见,插入位置和语句执行次数相差2,所以是代码中是a-2
除此之外,注意插入可以插入( size+1)个位置,而删除只能删除(size)个位置
如图所示,3个元素时能插入四个位置
3.尾插和头插的区别,首先尾插要额外处理第一次的情况,该情况有两个需要处理的点
一:把头指针链接上去
二:尾插需要一个额外的指针指向链表结尾(即要插入的节点的上一个),而第一次的时候,他是没有上一个的,类似插入元素
解决方法很简单,加一个判断,判断头指针是否为空(为空说明为第一次插入)为空则把头指针指到现在要插入的元素,不用把上一个的指针(即链表结尾的指针)的next指向现在要插入的元素,不为空则把上一个的指针(即链表结尾的指针)的next指向现在要插入的元素,最后把p指向链表尾端,即现在要插入的元素
头插一直在移动头指针,所以没有尾插的顾虑
#include<bits/stdc++.h>
using namespace std;
class node//定义一个节点类
{
int data;
node* next;
public:
node()
{
next = NULL;
}
friend class listt;
};
class listt//定义一个链表类,加t是为了防止与系统函数重名
{
node* head;
int size;
public:
listt()
{
head = NULL;
size = 0;
}
int get_element(int a)//获得位置为a的元素并返回
{
node* p = head;
if (a > size)
{
cout<<"error!";
exit(0);//如果位置不合法,则报错
}
else
{
for (int i = 0; i < a; i++)
{
p = p->next;
}
return p->data;
}
}
bool is_empty()//判断链表是否为空
{
return head == NULL;
}
void creat(int a[], int b)//以已有数组元素创建链表
{
node* s, * p = head;
size = b;
for (int i = 0; i < b; i++)//尾插法创建链表
{
s = new node;
s->data = a[i];//生成一个新节点
if (head == NULL)
{
head = s;//如果头指针为NULL,把他指向第一个
}
else
{
p->next = s;
}
p = s;
}
}
void insert(int x, int a)//插入一个节点
{
if (a > size + 1|| a < 0)
{
cout << "error!" << endl;
}
else
{
node* p = head;
node* s = new node;
s->data = x;
if (a == 1)
{
s->next = head;
head = s;
}
else
{
for (int i = 0; i < a - 2; i++)
{
p = p->next;
}
s->next = p->next;
p->next = s;
}
size++;
}
}
void deletee(int a)
{
if (a > size || a < 0)
{
cout << "error!" << endl;
}
else
{
node* p = head;
if (a == 1)
{
head = p->next;
delete p;
}
else
{
for (int i = 0; i < a - 2; i++)
{
p = p->next;
}
node* q = p->next;
p->next = p->next->next;
delete q;
}
size--;
}
}
void print()//打印链表
{
cout << "follow is the list:" << endl;
node* p = head;
for (int i = 0; i < size; i++)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
};
int main()
{
int b;
cin >> b;
int* a = new int[b];
for (int i = 0; i < b; i++)
{
cin >> a[i];
}
listt li;
li.creat(a, b);
li.print();
int x, y;
cin >> x >> y;
li.insert(x, y);
cin >> x;
li.print();
}
//1 2 3 4 5
void creat(int a[], int b)//头插法
{
node* s;
size = b;
for (int i = b - 1; i >= 0; i--)//从后往前依次加入元素
{
s = new node;
s->data = a[i];
s->next = head;//无需额外考虑第一次的情况
head = s;
}
}