#include <iostream>
//带头结点的单链表实现方法
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode,*LinkList;
bool InitList(LinkList &L);//初始化单链表,(带头节点)
void DestoryList(LinkList &L);//销毁单链表
int InsertList(LinkList &L,int i,int e);//向单链表位序第i个位置插入数据e
int InsertNextNode(LNode*p ,int e);//指定节点后插
int InsertPriorNode(LNode* p,int e);//指定节点前插
int DeleteList(LinkList &L,int i,int &e);//删除单链表第i个位置数据并打印出来
int DeleteNode(LNode*p);//指定节点的删除
int AlterList(LinkList &L,int i,int e);//将单链表第i个元素改为e;
LNode* GetElem(LinkList L,int i);//返回单链表第i个节点,按位查找
LNode* LocatedElem(LinkList L,int e);//按值查找,输出位序
int Length(LinkList L);//输出单链表表长
bool IsEmpty(LinkList L);//判断单链表是否为空
void PrintList(LinkList L);//打印单链表信息
//void IncreaseList(LinkList &L,int len);//扩充长度为len
//单链表的建立:尾插法、头插法:
//如果给你很多数据,要把他们存到一个单链表里面
//1、初始化一个单链表
//2、每次取一个元素,插入到链表的头部或尾部
LinkList ListInsertTail(LinkList&L);//尾插法建立单链表
LinkList ListInsertHead(LinkList&L);//头插法建立单链表
//一些常见题型
void MergeIncrease(LinkList &A,LinkList &B,LinkList &C);//合并递增单链表,A,B都是怎加的
void MergeDecrease(LinkList &A,LinkList&B,LinkList&C);//合并递减单链表
int FindAndDelete(LinkList&L,int i);//寻找并删除
void DeleteDuplicate(LinkList &L);//删除单增链表的重复元素
void DeleteMin(LinkList &L);//删除单链表中最小的值
void ReverseList(LinkList &L);//单链表原地置换
void Split(LinkList&A,LinkList&B);//将一个单链表分割为分别为奇数和偶数的两个链表
void RePrintList(LinkList&L);//逆序打印单链表
int FindKLast(LinkList&L,int k);//查询单链表中倒数k个元素
int main() {
LinkList L;
L=ListInsertTail(L);
/* InsertList(L,7,7);
PrintList(L);
InsertNextNode(L,0);*/
PrintList(L);
RePrintList(L);
PrintList(L);
/* int ans;
int flag;
flag=DeleteList(L,1,ans);
PrintList(L);
flag = AlterList(L,1,ans);//将单链表第i个元素改为e;
PrintList(L);*/
return 0;
}
bool InitList(LinkList &L)//初始化单链表,(带头节点)
{
L=(LNode*)malloc(sizeof(LNode));
if(L==NULL)return false;
L->next=NULL;
return true;
}
void DestoryList(LinkList &L)//销毁单链表
{
free(L);
}
int InsertList(LinkList &L,int i,int e)//向单链表位序第i个位置插入数据e
{
/* if(i<1)return 0;
LNode*p=L;
int j=0;
while(p->next!=NULL&&j<i-1)
{
p=p->next;
j++;
}
if(p==NULL)return 0;
LNode*q=(LNode*)malloc(sizeof(LNode));
q->data=e;
q->next=p->next;
p->next=q;
return 1;*/
LNode*p=GetElem(L,i-1);
InsertNextNode(p,e);
}
int InsertNextNode(LNode*p ,int e)//指定节点后插
{
if(p==NULL)return 0;
LNode*q=(LNode*)malloc(sizeof(LNode));
q->data=e;
q->next=p->next;
p->next=q;
return 1;
}
int InsertPriorNode(LNode* p,int e)//指定节点前插
{
if(p=NULL)return 0;
LNode* q=(LNode*)malloc(sizeof(LNode));
q->next=p->next;
p->next=q;
q->data=p->data;
p->data=e;
return 1;
}
int DeleteList(LinkList &L,int i,int &e)//删除单链表第i个位置数据
{
/* if(i<1)return 0;
LNode*p;
int j=0;
p=L;
while(p->next!=NULL&&j<i-1)
{p=p->next;j++;}
if(p==NULL)return 0;
LNode*q=p->next;
p->next=q->next;
e=q->data;
free(q);
return 1;*/
LNode*p=GetElem(L,i);
return DeleteNode(p);
}
int DeleteNode(LNode*p)//指定节点的删除,这个方法得默认后面还有节点
{
if(p==NULL)return 0;
LNode*q=p->next;
p->data=q->data;
p->next=q->next;
free(q);
return 1;
}
int AlterList(LinkList &L,int i,int e)//将单链表第i个元素改为e;
{
if(i<1)return 0;
LNode*p;
int j=0;
p=L;
while(p->next!=NULL&&j<i)
{
p=p->next;
j++;
}
if(p==NULL)return 0;
p->data=e;
return 1;
}
LNode* GetElem(LinkList L,int i)//输出单链表第i个位置元素,按位查找
{
if(i<1)return NULL;
LNode* p;
int j=0;
p=L;
while(p->next!=NULL&&j<i)
{
p=p->next;
j++;
}
if(j<i-1)
p=NULL;
return p;
}
LNode* LocatedElem(LinkList L,int e)//按值查找,输出位序
{
LNode*p=L;
while(p->next!=NULL&&p->data!=e)
p=p->next;
return p;//找到后返回该节点指针,否则返回空值
}
int Length(LinkList L)//输出单链表表长
{
LNode*p=L;
int len=0;
while(p->next!=NULL)
{p=p->next;
len++;}
return len;
}
bool IsEmpty(LinkList L)//判断单链表是否为空
{
if(Length(L)==0)return true;
return false;
}
void PrintList(LinkList L)//打印单链表信息
{
LNode*p=L;
int len=Length(L);
for(int i=0;i<len;i++)
{
p=p->next;
cout<<p->data<<endl;
}
}
LinkList ListInsertTail(LinkList&L)//尾插法建立单链表
{
int x;
L=(LNode*)malloc(sizeof(LNode));
LNode*s,*t=L;
scanf("%d",&x);
while(x!=9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
t->next=s;
t=s;
scanf("%d",&x);
}
t->next=NULL;
return L;
}
LinkList ListInsertHead(LinkList&L)//头插法建立单链表
{
LNode*s;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
int x;
scanf("%d",&x);
while(x=!9999)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
void MergeIncrease(LinkList &A,LinkList &B,LinkList &C)//合并递增单链表
{
LNode*p=A->next;
LNode*q=B->next;
LNode*r;
C=A;
C->next=A;
free(B);
r=C;
while(p!=NULL&&q!=NULL)
{
if(p->data<q->data)
{
r->next=p;
p=p->next;
r=r->next;
}
else
{
r->next=q;
q=q->next;
r=r->next;
}
}
if(p!=NULL)
r->next=p;
if(q!=NULL)
r->next=q;
}
void MergeDecrease(LinkList &A,LinkList&B,LinkList&C)//合并递减单链表
{//头插放置
LNode*p=A->next;
LNode*q=B->next;
C=A;
C->next=NULL;
LNode *r;
free(B);
while(q!=NULL&&p!=NULL)
{
if(p->data<=q->data)
{
r=p;
p=p->next;
r->next=C->next;
C->next=r;
}
else
{
r=q;
q=q->next;
r->next=C->next;
C->next=r;
}
}
while(p!=NULL)
{
r=p;
p=p->next;
r->next=C->next;
C->next=r;
}
while(q!=NULL)
{
r=q;
q=q->next;
r->next=C->next;
C->next=r;
}
}
int FindAndDelete(LinkList&L,int i)//寻找并删除
{
LNode*p=L->next;
while(p!=NULL) {
if (p->data != i)
p = p->next;
break;
}
if(p==NULL)return 0;
LNode*q=p->next;
p->data=q->data;
p->next=q->next;
free(q);
return 1;
}
void DeleteDuplicate(LinkList &L)//删除单增链表的重复元素
{
LNode*p,*q;
p=L->next;
while(p->next!=NULL)
{
if(p->data==p->next->data)
{
q=p->next;
p->next=q->next;
free(q);
}
else
p=p->next;
}
}
void DeleteMin(LinkList &L)//删除单链表中最小的值
{
LNode*p=L->next;
LNode*prep=L;
LNode*min=L->next;
LNode* premin=L;
while(p!=NULL)
{
if(p->data<min->data)
{
min=p;
premin=prep;
}
prep=p;
p=p->next;
}
premin->next=min->next;
free(min);
}
void ReverseList(LinkList &L)//单链表原地置换
{
LNode*p,*q;
p=L->next;
L->next=NULL;
while(p!=NULL)
{
q=p->next;
p->next=L->next;
L->next=p;
p=q;
}
}
void Split(LinkList&A,LinkList&B)//将一个单链表分割为分别为奇数和偶数的两个链表
{
//p用来扫描,但是指向的要删除节点的前驱
//q用来临时保存要删除的节点
//r用来指向B中的终端节点
LNode*p,*q,*r;
B=(LinkList)malloc(sizeof(LNode));
B->next=NULL;
p=A;
r=B;
while (p != NULL) {
if (p->next->data%2 == 0) {
q = p->next;
p->next = p->next->next;
r->next = q;
r = q;
q->next = NULL; // 不写这句话绝对出事
} else {
p = p->next;
}
}
}
void RePrintList(LinkList &L)//逆序打印单链表,栈-》递归
{
LNode*p=L->next;
if(p!=NULL)
{
RePrintList(p);
printf("---%d\n",p->data);
}
}
int FindKLast(LinkList&L,int k)//查询单链表中倒数k个元素
{
LNode*p,*q;
p=L->next;
q=L;
int i=1;
while(p!=NULL)
{
p=p->next;
i++;
if(i>k)q=q->next;
}
if(q==L)return 0;
else {
printf("%d",q->data);
return 1;
}
}
3、带头结点的单链表基本操作
于 2022-05-19 09:15:40 首次发布