C++实现单链表
链表和数组的区别
数组的特点:
- 在内存中连续存放,可以通过下标迅速访问数组的任何元素,数组的插入和删除数据效率低,因为插入位置后的元素都要向后移动,删除位置后的元素都要向前移动。
- 随机读取效率高,因为数组是连续的,知道每一个数据的内存地址,可以直接找到该地址的数据。
- 数组需要预留空间,在使用前要先申请占内存的大小,可能会浪费空间,并且数组不利于扩展,数组所定义的空间不够时需要重新定义数组
链表的特点:
- 内存中非顺序存储,而是通过元素中的指针链接在一起。
- 访问元素需要从第一个元素开始–顺序查找
- 增加和删除相对简单,只需要修改指针不需要移动元素
- 链表不需要指定大小,扩展比较方便,增删比较方便
链表和数组的优缺点
数组的优点
- 随机访问强
- 查找速度快
数组的缺点
- 插入和删除效率低
- 可能浪费内存
- 内存空间要求高,必须要有足够连续的内存空间
- 数组大小固定 ,不能动态扩展
链表的优点
- 插入删除速度快
- 内存利用率高,不会浪费内存
- 大小没有固定、拓展很灵活
链表的缺点
- 不能够随机查找,查找效率低
类的声明源码
#ifndef CLION_LINKLIST_H
#define CLION_LINKLIST_H
#include <iostream>
using namespace std;
struct Node {
public:
int data;
Node *next;
Node() : data(0), next(nullptr) {}
Node(int x) : data(x), next(nullptr) {}
Node(int x, Node *next) : data(x), next(nullptr) {}
};
class LinkList {
public:
Node *head;
LinkList(){head= nullptr;}
~LinkList(){Deleteall();}
void InitList();;
void Deleteall();
void HeadCreat(int n);
void TailCreate(int n);
int Length();
Node *GetT(const int &x);
Node *GetIndex(const int &i);
bool Insert(const int val,int i);
bool Delete(const int &val);
void Print();
};
#endif
具体实现源码
#include "LinkList.h"
void LinkList::InitList() {
Deleteall();
head= nullptr;
}
void LinkList::HeadCreat(int n) {
Deleteall();
Node *s;
Node *p=new Node();
p->next=nullptr;
int i;
for(int i=0;i<n;i++){
s=new Node(i+10);
s->next=p->next;
p->next=s;
}
head=p;
}
void LinkList::TailCreate(int n) {
Deleteall();
Node *s;
Node *pre= nullptr;
Node *p=new Node();
p->next= nullptr;
for(int i=0;i<n;i++){
s=new Node(i+100);
if(pre==nullptr){
p->next=s;
pre=s;
}else{
pre->next=s;
pre=s;
}
}
head=p;
}
void LinkList::Print() { Node *p;
p=head->next;
while(p){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void LinkList::Deleteall() {
Node *p=head,*q;
while(p){
q=p->next;
delete p;
p=q;
}
head== nullptr;
}
int LinkList::Length() {
Node *p=head->next;
if(p== nullptr){
return 0;
}
int count=0;
while(p){
count++;
p=p->next;
}
return count;
}
Node *LinkList::GetT(const int &x) {
Node *p=head;
if(p== nullptr){
return nullptr;
}
while(p){
if(p->data==x){
return p;
}
p=p->next;
}
return nullptr;
}
Node *LinkList::GetIndex(const int &i) {
if(i>this->Length()){
return nullptr;
}
Node *p=head->next;
int count=0;
while(p!= nullptr&&count!=i-1){
count++;
p=p->next;
}
return p;
}
bool LinkList::Insert(const int val, int i) {
if(i<0||i>this->Length()){
return false;
}
if(i==this->Length()){
Node *p=head->next;
while (p->next){
p=p->next;
}
Node *newNode=new Node(val);
p->next=newNode;
return true;
}
if(i==0){
Node *newNode=new Node(val);
newNode->next=head->next;
head->next=newNode;
return true;
}
Node *p=head->next;
for(int j=0;j<i-2;j++){
p=p->next;
}
Node *newNode=new Node(val);
newNode->next=p->next;
p->next=newNode;
return false;
}
bool LinkList::Delete(const int &val) {
Node *p=head->next,*q=head;
while(p->data!=val&&p!= nullptr){
p=p->next;
q=q->next;
}
if(p== nullptr){
return false;
}
q->next=p->next;
delete p;
p= nullptr;
return true;
}
int main(){
LinkList L;
L.InitList();
L.TailCreate(10);
L.Print();
cout<<L.Length()<<endl;
Node *temp=L.GetT(101);
if(temp== nullptr){
cout<<"不存在"<<endl;
}else{
cout<<temp->data<<endl;
}
temp=L.GetIndex(4);
if(temp!= nullptr){
cout<<temp->data<<endl;
}
L.Insert(20,10);
L.Insert(10,0);
L.Insert(55,3);
L.Print();
L.Delete(10);
L.Print();
L.Delete(55);
L.Print();
L.Delete(20);
L.Print();
return 0;
}