从链表的实现方式可以把链表分为单链表,循环链表,双向链表。
- 单链表指的是链表中的元素的指向只能指向链表中的下一个元素或者为空,元素之间不能相互指向。也就是一种线性链表。
- 双向链表即是这样一个有序的结点序列,每个链表元素既有指向下一个元素的指针,又有指向前一个元素的指针,其中每个结点都有两种指针,即left和right。left指针指向左边结点,right指针指向右边结点。
- 循环链表指的是在单向链表和双向链表的基础上,将两种链表的最后一个结点指向第一个结点从而实现循环。
表的顺序表示的优点是随机存取表中的任意元素,但是在做插入或删除操作时,需移动大量元素。
表的链式表示,在随机插入元素时没有顺序表示的缺陷,但同时不能对元素进行随机存取。
以下为单链表的实现:
数据结构:
//节点
struct MyNode{
int data;//数据
MyNode *next;//下一个节点
int pos;//节点位置
};
//链表
struct MyList{
int length=0;//链表长度
MyNode *node=nullptr;
};
功能实现:
MyList *InitList_5();//初始化 5个长度
void Ergodic(MyList *list);//遍历输出
void InsertNodeByPos(MyList *list,int pos,int data);//根据位置插入
MyNode *FindNodeByData(MyList *list, int data);//根据数据查找节点
MyNode *FindNodeByPos(MyList *list, int pos);//根据位置查找节点
int FindDataByPos(MyList *list,int pos);//根据位置查找数据
void UpdataDataByPos(MyList *list,int newdata,int pos);//根据位置更新节点数据
void UpdataDataByNode(MyNode *node,int newdata);//更新节点数据
void deleteNodeByPos(MyList *list,int pos);
void deleteAll(MyList *list);
MyList *InitList_5()
{
int num[5]={1,2,3,4,5};
MyList *list=new MyList();
list->node=new MyNode();
list->node->data=num[0];
list->node->next=nullptr;
list->node->pos=list->length;
list->length++;
MyNode *temp=list->node;
for(int i=1;i<5;i++)
{
MyNode *temp2=new MyNode();
temp2->data=num[i];
temp2->next=nullptr;
temp2->pos=temp->pos+1;
temp->next=temp2;
temp=temp->next;
list->length++;
}
return list;
}
void Ergodic(MyList *list)
{
if(list->node==nullptr)
{
return;
}
MyNode *temp=list->node;
cout<<temp->data;
while(temp->next!=nullptr)
{
temp=temp->next;
cout<<"--->"<<temp->data;
}
cout<<endl;
}
MyNode *FindNodeByData(MyList *list,int data)
{
if(list->length==0)
return nullptr;
MyNode *result;
MyNode *temp=list->node;
while(temp!=nullptr)
{
if(temp->data==data)
result=temp;
temp=temp->next;
}
return result;
}
MyNode *FindNodeByPos(MyList *list, int pos)
{
if(list->length==0)
return nullptr;
MyNode *result;
MyNode *temp=list->node;
while(temp!=nullptr)
{
if(temp->pos==pos)
result=temp;
temp=temp->next;
}
return result;
}
int FindDataByPos(MyList *list,int pos)
{
if(list->length==0)
return -1;
if(pos>list->length)
return -1;
int result;
MyNode *temp=list->node;
while(temp!=nullptr)
{
if(temp->pos==pos)
{
result=temp->data;
return result;
}
temp=temp->next;
}
}
void InsertNodeByPos(MyList *list,int pos,int data)
{
if(pos>=list->length)
{
if(list->length==0)
{
MyNode *temp2=new MyNode();
temp2->data=data;
temp2->pos=0;
temp2->next=nullptr;
list->node=temp2;
}
else {
MyNode *temp=FindNodeByPos(list,list->length-1);
MyNode *temp2=new MyNode();
temp2->data=data;
temp2->pos=temp->pos+1;
temp2->next=nullptr;
temp->next=temp2;
}
}
else {
if(pos==0)
{
MyNode *temp2=new MyNode();
temp2->data=data;
temp2->pos=0;
temp2->next=list->node;
list->node=temp2;
MyNode *temp3=temp2;
while(temp3->next!=nullptr)
{
temp3->next->pos=temp3->next->pos+1;
temp3=temp3->next;
}
}
else {
MyNode *temp=FindNodeByPos(list,pos-1);//获取位置的前一个位置
MyNode *temp2=new MyNode();
temp2->data=data;
temp2->pos=temp->pos+1;
temp2->next=FindNodeByPos(list,pos);
temp->next=temp2;
MyNode *temp3=temp2;
while(temp3->next!=nullptr)
{
temp3->next->pos=temp3->next->pos+1;
temp3=temp3->next;
}
}
}
list->length++;
}
void UpdataDataByPos(MyList *list,int newdata,int pos)
{
if(pos>list->length||list->length==0)
return;
MyNode *temp=list->node;
// while(temp!=nullptr)
// {
// if(temp->pos==pos)
// {
// temp->data=newdata;
// break;
// }
// if(temp->next!=nullptr)
// {
// temp=temp->next;
// }
// }
do
{
if(temp->pos==pos)
{
temp->data=newdata;
break;
}
temp=temp->next;
}
while(temp->next!=nullptr);
}
void UpdataDataByNode(MyNode *node,int newdata)
{
if(node==nullptr)
return;
node->data=newdata;
}
void deleteNodeByPos(MyList *list,int pos)
{
if(pos>list->length||list->length==0)
return;
if(pos==0)
{
if(list->length>1)
{
MyNode *temp2=list->node;
list->node=list->node->next;
delete temp2;
temp2==nullptr;
//更新位置
MyNode *temp=list->node;
while(temp->next!=nullptr)
{
temp->pos=temp->pos-1;
temp=temp->next;
}
}
else {//list->length==pos==1
delete list->node;
list->node=nullptr;
}
}
else {
MyNode *temp=list->node;
MyNode *temp2=list->node->next;
while(temp2!=nullptr)
{
if(temp2->pos==pos)
{
if(temp2->next!=nullptr)
{
temp->next=temp2->next;
delete temp2;
temp2=nullptr;
MyNode *temp3=temp->next;
while(temp3!=nullptr)//更新位置
{
temp3->pos=temp3->pos-1;
temp3=temp3->next;
}
break;
}
else {
delete temp2;
temp2=nullptr;
temp->next=nullptr;
}
}
else {
temp=temp2;
temp2=temp2->next;
}
}
}
list->length--;
}
void deleteNodeByPos(MyList *list,int pos,int count)
{
if(pos>list->length||list->length==0||count==0||count>list->length||(pos+count)>list->length)
return;
if(count==1)
deleteNodeByPos(list,pos);
else {
if(pos==0)
{
MyNode *temp2=list->node;
list->node=FindNodeByPos(list,count);
for(int i=0;i<count;i++)
{
MyNode *temp3=temp2->next;
delete temp2;
temp2=temp3;
}
//更新位置
MyNode *temp=list->node;
while(temp!=nullptr)
{
temp->pos=temp->pos-count;
if(temp->next!=nullptr)
temp=temp->next;
}
}
else {
MyNode *temp2=FindNodeByPos(list,pos);
MyNode *temp=FindNodeByPos(list,pos-1);
temp->next=FindNodeByPos(list,pos+count);
for(int i=pos;i<pos+count;i++)
{
MyNode *temp3=temp2->next;
delete temp2;
temp2=temp3;
}
//更新位置
MyNode *temp4=FindNodeByPos(list,pos);
while(temp4!=nullptr)
{
temp4->pos=temp4->pos-count;
if(temp4->next!=nullptr)
temp4=temp4->next;
else {
break;
}
}
}
list->length-=count;
}
}
void deleteAll(MyList *list)
{
if(list->length==0)
return;
MyNode *temp=list->node;
while(temp!=nullptr)
{
if(temp->next!=nullptr)
{
MyNode *temp2=temp->next;
delete temp;
temp=temp2;
}
else {
delete temp;
temp=nullptr;
}
}
}
测试:
int main()
{
MyList *list=InitList_5();//初始化list长度为5
Ergodic(list);//遍历输出
cout<<list->length<<endl;
cout<<FindNodeByData(list,3)->next->pos<<endl;//3的下一个为4
cout<<FindDataByPos(list,3)<<endl;
InsertNodeByPos(list,3,10);//插入
Ergodic(list);//遍历输出
InsertNodeByPos(list,3,15);//插入
Ergodic(list);//遍历输出
InsertNodeByPos(list,0,20);//插入
Ergodic(list);//遍历输出
InsertNodeByPos(list,20,999);//插入
Ergodic(list);//遍历输出
UpdataDataByPos(list,888,3);//更新
Ergodic(list);//遍历输出
deleteNodeByPos(list,3);//删除
Ergodic(list);//遍历输出
deleteNodeByPos(list,1,2);//删除
Ergodic(list);//遍历输出
return 0;
}