单链表和循环单链表的基本操作
/**
2021.8.23
lkm
该项目里面包含单链表操作以及循环单链表操作,
注意:循环单链表判断条件为p!=L;
**/
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
int data; //数据域
struct LNode *next; //指针域
}LNode,*LinkList;
//1.头插法建立链表,即将待插入的结点插在第一个位置//
LinkList CreateList( LinkList L,int n) //--L-- p
{
LinkList p;
int i;
L=(LinkList)malloc(sizeof(LNode));//创建头结点 获取LNode的字段长度,然后强转为Linklist类型
L->next=NULL;
for(i=0;i<n;i++)
{
p=(LinkList)malloc(sizeof(LNode));//创建新结点、
scanf("%d",&(p->data));
p->next=L->next;//p的后继等于L的后继
L->next=p;//将L的后继是p
}
return L;
}
//循环单链表用尾插法建立链表,即将待插入的结点插在尾部位置
LinkList CreateList1( LinkList L,int n) /// --p--L
{
LinkList p,r;
int i;
L=(LinkList)malloc(sizeof(LNode));//创建头结点 获取LNode的字段长度,然后强转为Linklist类型
L->next=NULL;
r=L;
for(i=0;i<n;i++)
{
p=(LinkList)malloc(sizeof(LNode));//创建新结点、
scanf("%d",&(p->data));
//将p转为实际头结点
p->next=NULL;
r->next=p;
r=p;
}
p->next=L;
return L;
}
//2.输出链表//
void ShowList(LinkList L,int n)
{
int i=1;
LinkList p;
p=L->next;
while( p && i<n) //单链表输出
//while( p!=L && i<n) //循环单链表输出链表
{
printf("the data %d is %d\n",i,p->data);
p=p->next;
i++;
}
}
void ShowList1(LinkList L,int n)
{
int i=1;
LinkList p;
p=L;
while( p && i<n) //单链表输出
//while( p!=L && i<n) //循环单链表输出链表
{
printf("the data %d is %d\n",i,p->data);
p=p->next;
i++;
}
}
//3.求链表的长//
int Length(LinkList L)
{
int l=0;
LinkList p;
p=L->next;
while(p) //单链表 p!=NULL
//while(p!=L) //循环单链表输出链表长度 p!=L
{
l=l+1;
p=p->next;
}
return l;
}
//4.在链表中第i个位置插入值为e结点//
LinkList Insert(LinkList L,int i,int e)
{
LinkList p,s;
int j=1;
p=L;
while(p && j<i)
{
p=p->next;
j++;
}
s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return L;
}
//5.删除链表中的第i个结点//
LinkList Delete(LinkList L,int i)
{
LinkList p,q;
int j=1;
p=L;
while(p && j<i)//
{
p=p->next;
j++;
}
q=p->next;
p->next=q->next;
free(q);
return L;
}
//6.取出链表中第i个结点的值//
int GetData(LinkList L,int i)
{
LinkList p;
int e;
int j=1;
p=L->next;
while(p&&j<i)
//while(p!=L && j<i)
{
p=p->next;
j++;
}
e=p->data;
return e;
}
//7.找链表中结点值为d的前驱结点的值//
int Prior(LinkList L,int d)
{
LinkList p;
p=L->next;
while(p&&p->data!=d)
//while(p!=L&&p->data!=d)
{
p=p->next;
}
return p->data;
}
//8.单链表将两个链表合并,返回合并后链表的头结点Hc//
LinkList MergeList(LinkList Ha,LinkList Hb)
{
LinkList a,b,c;
LinkList Hc;
Hc=(LinkList)malloc(sizeof(LNode));
c=Hc;
c->next=NULL;
a=Ha->next;
b=Hb->next;
while(a && b )
{
if(a->data<=b->data)
{
c->next=a;
c=a;
a=a->next;
}
else {
c->next=b;
c=b;
b=b->next;
}
}
c->next=a?a:b;//若a为NULL,c->next=b,反之亦然。
//free(Ha);
free(Hb);
return Hc;
}
//9.循环单链表将两个链表合并,此算法采用尾指针首尾相连
LinkList MergeList1(LinkList Ha,LinkList Hb)
{
LNode *p; //与下面三行可以替换
/**
LinkList p;
p=(LinkList)malloc(sizeof(LNode));
p->next=NULL;
**/
p=Ha->next; //保存链表Ha的头结点地址
Ha->next=Hb->next->next; //Ha的头结点连到Hb的尾结点
Hb->next=p; //链表Hb的头结点换成链表Ha的头结点
return Hb;
}
//10.判断链表是否有环
bool hasCycle(LinkList L) {
LinkList p = L;
LinkList q = L;
while(q && q->next){
p = p->next;
q = q->next->next;
if (p == q)
return true;
}
return false;
}
//11.反转链表(单链表)
LinkList ReverseList(LinkList L){
LinkList p,q,temp;
if(L==NULL){
return NULL;//链表为空
}
if(L->next==NULL){
return L;//只有一个节点
}
p=L;
q=L->next;
L->next=NULL;
while(q!=NULL){
temp=q->next;
q->next=p;
p=q;
q=temp;
}
return p;
}
//12.反转链表指定区域
LinkList ReversePositionList(LinkList L, int m, int n){
LinkList r,p,q,temp;
p=(LinkList)malloc(sizeof(LNode));
if(L == NULL){//链表为空
return NULL;
}
if(L->next == NULL) {//只有一个头结点
return L;
}
p=L;
r=p;
int i=1;
while(r && i<m) {//遍历到m的前一个位置
r=r->next;
i++;
}
temp=r->next;
q=temp->next;
while(m<n){
temp->next=q->next;
q->next=r->next;
r->next=q;
q=temp->next;
m++;
}
return p;
}
int main()
{
LinkList La,Lb;
int n,len;
LinkList pa,pb,pc;//新结点
printf("input the length of list a:");
scanf("%d\n",&n);
pa=CreateList(La,n);
len=Length(pa);
printf("the list length is %d \n",Length(pa));
ShowList(pa,len+1);
printf("\n");
printf("input the length of list b:");
scanf("%d\n",&n);
pb=CreateList(Lb,n);
len=Length(pb);
printf("the list length is %d \n",Length(pb));
ShowList(pb,len+1);
printf("\n");
printf("pb链表是否有环?0/1 \n");
printf("%d\n",hasCycle(pb));
//找到链表La的结点值为3的前驱结点并输出//
printf("the Prior of %d is %d\n",3,Prior(pa,3));
//在链表La的第4个位置插入值为63的结点后输出链表//
pa=Insert(pa,4,63);
len=Length(pa);
printf("链表La的4个位置插入值为63\n");
printf("the inserted list length is %d \n",Length(pa));
ShowList(pa,len+1);
//删除链表Lb的第3个位置的结点后输出链表//
pb=Delete(pb,3);
len=Length(pb);
printf("删除链表Lb的第3个位置的结点\n");
printf("the deleteed list length is %d \n",Length(pb));
ShowList(pb,len+1);
//合并链表La、Lb,并输出//
pc=MergeList(pa,pb);
len=Length(pc);
printf("\nthe pc list length is %d \n",Length(pc));
ShowList(pc,len+1);
//反转指定区域链表
pc=ReversePositionList(pc,2,3);
printf("\npc链表2到3区域反转:\n");
len=Length(pc);
ShowList(pc,len+1);
//反转链表
pc=ReverseList(pc);
printf("\npc链表反转:\n");
len=Length(pc);
ShowList1(pc,len+1);
}
看到最后还不留下你的赞和小钱钱~