单链表基础操作
刷题的更新断断续续,到学期中旬,感觉知识越来越难,要学好花费的时间越来越多,链表真的挺薄弱的,学习C的时候,老师一笔带过,现在学数据结构一点点补上这块缺漏,每天进步一点点,废话不多说上代码(如果发现代码有错,请积极评论,马上修改,优化建议也可)
我写的是带头结点的单链表
//有头结点的线性表基础操作
#include<iostream>
#include<malloc.h>
using namespace std;
typedef struct LNode{
int data; //数字域
struct LNode *next;//指针域
}LNode ,*LinkList;
//创建一个线性表并且填充前n项,使用头插法
void CreatList_Headinsert(LinkList &L,int n)
{
L = (LinkList)malloc(sizeof(LNode));//为L申请一个头结点
L->next = NULL;
int data;
for(int i = n;i > 0;i--)
{
cin>>data;
LNode *p = (LNode*)malloc(sizeof(LNode));//申请一个新的结点
p->data = data;
p->next = L->next;//先将新结点接上头结点之后的数据
L->next = p; //再将头结点接上新的结点
}
/*使用头插法后,先插入的数字会被挤到后面的位置,可应用于
单链表的逆序输出*/
}
//后插操作
bool InsertNextNode(LNode *p,int e)
{
if(p == NULL)
{
return false;
}
LNode*s = (LNode*)malloc(sizeof(LNode));
if(!s)
{
return false;
}
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//不传入头指针的前插操作
bool InsertPriorNode(LNode*p,int e)
{
if(p == NULL)
{
return false;
}
LNode *s = (LNode*)malloc(sizeof(LNode));
if(!s)
{
return false;
}
s->next = p->next;
p->next = s;
s->data = p->data;
p->data = e;
return true;
/*将新生成的结点接到需要前插的结点的后面,然后将两个结点的
数据互换,间接达到前插的目的*/
}
//创建一个线性表并且填充前n项,使用尾插法
void CreatLinst_Tailinsert(LinkList &L,int n)
{
L = (LinkList)malloc(sizeof(LNode));//为L申请一个头结点
L->next = NULL;
int data;
LNode *p = (LNode*)malloc(sizeof(LNode));//p指针指向当前所扫描到的结点
p = L;
for(int i = 1;i <=n; i++)
{
cin>>data;
LNode *s = (LNode*)malloc(sizeof(LNode));
s->data = data;
s->next = p->next;//连接新结点
p->next = s;
p = s;//使得p始终指向最后一个结点
}
}
//按位查找
LNode * GetElem(LinkList L,int i)
{
if(i<0)
{
return NULL;
}
LNode *p = (LNode*)malloc(sizeof(LNode));
p = L;
int j = 0;
while(p!=NULL&&j<i)
{
p = p->next;
j++;
}
if(p==NULL)
{
return NULL;
}
return p;
}
//按值查找返回结点
LNode* GetElem_number(LinkList L,int e)
{
LNode *p = (LNode*)malloc(sizeof(LNode));
p = L;
int j = 0;
while(p!=NULL&&p->data!=e)
{
p=p->next;
j++;
}
if(p==NULL)
{
return NULL;
}
return p;
}
//按值查找
int GetElem_L(LinkList L,int e)
{
LNode *p = (LNode*)malloc(sizeof(LNode));
p = L;
int j = 0;
while(p!=NULL&&p->data!=e)
{
p=p->next;
j++;
}
if(p==NULL)
{
return 0;
}
return j;
}
//创建一个线性表并且填充前n项,使其成为非递减有序
void CreatLinkR1(LinkList &L,int n)
{
L = (LinkList)malloc(sizeof(LNode));//为L申请一个头结点
L->next = NULL;
int data;
LNode *p = (LNode*)malloc(sizeof(LNode));
p = L;
for(int i = 1;i <=n; i++)
{
cin>>data;
LNode *s = (LNode*)malloc(sizeof(LNode));
s->data = data;
s->next = p->next;//连接新结点
p->next = s;
p = s;//使得p始终指向最后一个结点
}
LNode *a = (LNode*)malloc(sizeof(LNode));
LNode *b = (LNode*)malloc(sizeof(LNode));
for(a = L->next;a!=NULL;a=a->next)
{
for(b = L->next;b!=NULL;b=b->next)
{
if(a->data<b->data)
{
int t = b->data;
b->data = a->data;
a->data = t;
}
}
}
}
//打印线性表
void PrintList(LinkList L)
{
LNode *p = (LNode*)malloc(sizeof(LNode));
p = L->next;
while(p != NULL )
{
cout<<p->data<<" ";
p = p->next;
}
}
//计算链表的长度
int LengthList(LinkList L)
{
LNode *p = (LNode*)malloc(sizeof(LNode));
p = L;
int count = 0;
while(p!=NULL)
{
p = p->next;
count++;
}
if(count ==0)
{
return 0;
}
return count-1;
}
//插入到指定位序
bool Insert_after_Node(LinkList &L,int i,int e)
{
//设置头结点为第0个结点,所以小于0的结点为非法结点
if(i < 0)
{
return false;
}
LNode *p = (LNode*)malloc(sizeof(LNode));//p指针指向当前所扫描到的结点
if(!p)
{
return false;
}
p = GetElem(L,i-1);
if(p == NULL)//当前输入的插入位置超出范围,非法插入
{
return false;
}
LNode *s = (LNode*)malloc(sizeof(LNode));
if(!s)
{
return false;
}
s->data = e;
s->next = p->next;//连接新结点
p->next = s;
return true;
}
//删除指定位置的结点
bool ListDelete(LinkList &L,int i,int &e)
{
if(i<0)
{
return false;
}
LNode *p = (LNode*)malloc(sizeof(LNode));
if(!p)
{
return false;
}
p = GetElem(L,i-1);
if(p ==NULL)
{
return false;
}
LNode *q = (LNode*)malloc(sizeof(LNode));
q = p->next;//q指向要删除的结点
e = q->data;
p->next = q->next;
free(q);
return true;
}
//按值删除结点(有多个结点也一并删除)
bool ListDelete_number(LinkList &L,int e)
{
LNode *p = (LNode*)malloc(sizeof(LNode));
LNode *s = (LNode*)malloc(sizeof(LNode));
LNode *k = (LNode*)malloc(sizeof(LNode));
p = L;
k = L;
int j = 0;
int i = 0;
int len = LengthList(L);
if(len == 0)//如果长度为0 则说明链表为空
{
return false;
}
while(k!=NULL&&k->data!=e)//外部找一次看看是否有这个数
{
k = k->next;
}
if(k==NULL)//如果没有则不存在这个数
{
return false;
}
k = L;
while(1)
{
while(p!=NULL&&p->data!=e)//找到当前值所在的结点位置
{
p = p->next;
j++;
}
s = GetElem(L,j-1);//找到前结点
LNode *q = (LNode*)malloc(sizeof(LNode));
q = s->next;//q指向要删除的结点
s->next = q->next;
len--;//链表的长度减1
j=0;//清除所找到的结点重新开始
p = L;
free(q);
while(k!=NULL&&k->data!=e)//保持链表的循环进度
{
k = k->next;
}
if(k==NULL)
{
return true;
break;
}
else
{
k = L;
}
}
}
int main()
{
LinkList L;
cout<<"输入要生成的数据:"<<endl;
CreatList_Headinsert(L,10);
cout<<"生成的头插法链表为:"<<endl;
PrintList(L);
cout<<endl;
cout<<"输入要生成的数据:"<<endl;
CreatLinst_Tailinsert(L,10);
cout<<"生成的尾插法的链表为:"<<endl;
PrintList(L);
cout<<endl;
//测试前插和后插入到第2个结点前后
LNode *s = (LNode*)malloc(sizeof(LNode));
s = L;
int i = 0;
while(s!=NULL&&i<2)
{
s = s->next;
i++;
}
if(InsertNextNode(s,2)==false)
{
cout<<"插入失败!"<<endl;
}
else
{
cout<<"后插入后的链表为:"<<endl;
PrintList(L);
cout<<endl;
}
if(InsertPriorNode(s,2)==false)
{
cout<<"插入失败!"<<endl;
}
else
{
cout<<"前插入后的链表为:"<<endl;
PrintList(L);
cout<<endl;
}
if(Insert_after_Node(L,3,3)==false)
{
cout<<"插入失败!"<<endl;
}
else
{
cout<<"插入后的链表为:"<<endl;
PrintList(L);
cout<<endl;
}
LNode *r = GetElem(L,2);
cout<<"第2个结点的数值为:"<<r->data<<endl;
LNode *w = GetElem_number(L,27);
if(w == NULL)
{
cout<<"查询的数据不存在这个链表中!"<<endl;
}
else
{
cout<<"所查询的结点为"<<w->data<<endl;
}
cout<<"链表的长度为:"<<LengthList(L)<<endl;
int number ;
if(ListDelete(L,2,number)==false)
{
cout<<"删除的结点非法!"<<endl;
}
else
{
cout<<"所删除的结点的数据为:"<<number<<endl;
}
if(ListDelete_number(L,27)==false)
{
cout<<"链表为空!"<<endl;
}
else
{
cout<<"删除重复数据后的链表为:"<<endl;
PrintList(L);
cout<<endl;
}
cout<<"链表的长度后:"<<LengthList(L);*/
cout<<"输入要生成的数据:"<<endl;
CreatLinkR1(L,10);
cout<<"非递减链表为:"<<endl;
PrintList(L);
cout<<endl;
if(Delete_LL(L)==false)
{
cout<<"删除失败!"<<endl;
}
else
{
cout<<"删除重复数据后的链表为:"<<endl;
PrintList(L);
cout<<endl;
}
cout<<"链表的长度:"<<LengthList(L);
}