嗯,咳咳 ~ ~,没错是我,我又来了,最近正在疯狂研读《数据结构与算法》,有点快要上瘾的节奏了,此篇还是有关链表的知识——循环链表。话不多说,我们代码上见真章吧!若有不足之处,望各位大佬指点一二!

1.循环单链表:

1.1.函数声明:

#include<stdio.h> #include<stdlib.h> typedef struct node
{
 int date;
 struct node *next;
}node,*pnode;
/* void initlink(pnode *L);//初始化链表 void createlink(pnode L);//创建链表 void traverselink(pnode L);//遍历链表 pnode get_element(pnode L,int i,pnode *pre);//获取链表中第i节点及其前驱节点 void insert_element(pnode L);//在特定位置插入新节点 void delete_element(pnode L);//删除特定位置节点 pnode get(pnode L,int val,pnode *pre);//获取特定元素节点 void insert(pnode L);//在特定元素之前插入元素 void deletes(pnode L);//删除特定元素节点 int main();//主函数 */

1.2.初始化、创建链表:

void initlink(pnode *L)//初始化链表
{
 *L=(pnode)malloc(sizeof(node)); if(!*L)
 {
  printf("内存分配失败!\n");
  exit(-1);
 }
 (*L)->next=*L;
 return;
}

void createlink(pnode L)//创建链表
{
 pnode q,p;
 int i,len;
 p=L;
 printf("请输入创建链表的长度len:\n");
 scanf("%d",&len);
 putchar(10);
 for(i=0;i<len;i++)
 {
  q=(pnode)malloc(sizeof(node)); if(!q)
  {
      printf("内存分配失败!\n");
      exit(-1);
  }
  printf("请输入初始化元素:\n");
  scanf("%d",&q->date);
  q->next=p->next;
  p->next=q;
  p=q;
 }
 putchar(10);
 return;
}

1.3.遍历函数:

void traverselink(pnode L)//遍历链表
{
 pnode h=L->next; while(h!=L)
 {
  printf("%d\n",h->date);
  h=h->next;
 }
 putchar(10);
 return;
}


1.4.对链表中特定位置进行增删操作:

pnode get_element(pnode L,int i,pnode *pre)//获取链表中第i节点及其前驱节点
{
 pnode p;
 int k;
 p=L;
 k=0; while(p!=NULL && k<i)
 {
  *pre=p;
  p=p->next;
  k++;
 }
 if(p==NULL) *pre=NULL;
 return p;
}

void insert_element(pnode L)//在特定位置插入新节点
{
 pnode h,k,pre;
 int i;
 k=(pnode)malloc(sizeof(node)); if(!k)
 {
  printf("内存分配失败!\n");
  exit(-1);
 }
 printf("请输入插入元素的位置i及插入的元素:\n");
 scanf("%d %d",&i,&k->date);
 h=get_element(L,i,&pre); if(!pre)
 {
  printf("i值有误\n");
  exit(-1);
 }
 pre->next=k;
 k->next=h;
 putchar(10);
 return;
}

void delete_element(pnode L)//删除特定位置节点
{
 pnode h,pre;
 int i;
 printf("请输入要删除元素在链表中的位置i:\n");
 scanf("%d",&i);
 putchar(10);
 h=get_element(L,i,&pre); if(!pre)
 {
  printf("i值有误\n");
  exit(-1);
 }
 printf("删除的元素为:%d\n",h->date);
 pre->next=h->next;
 free(h);
 putchar(10);
 return;
}


1.5.对链表中特定元素进行增删操作:

pnode get(pnode L,int val,pnode *pre)//获取特定元素节点
{
 pnode p;
 *pre=L;
 p=L->next; while(p!=NULL && p->date!=val)
 {
  *pre=p;
        p=p->next;
 }
 if(p==NULL) *pre=NULL;
    return p;
}

void insert(pnode L)//在特定元素之前插入元素
{
 pnode k,h,pre;
 int val;
 k=(pnode)malloc(sizeof(node)); if(!k)
 {
  printf("内存分配失败!\n");
  exit(-1);
 }
 printf("请输入要插入链表中元素val及插入的元素:\n");
 scanf("%d %d",&val,&k->date);
 putchar(10);
 h=get(L,val,&pre); if(!pre)
 {
  printf("元素不存在\n");
  exit(-1);
 }
 k->next=h;
 pre->next=k;
 putchar(10);
 return;
}

void deletes(pnode L)//删除特定元素节点
{
 pnode h,pre;
 int val;
 printf("请输入要删除元素val:\n");
 scanf("%d",&val);
 putchar(10);
 h=get(L,val,&pre); if(!pre)
 {
  printf("i值有误\n");
  exit(-1);
 }
 pre->next=h->next;
 free(h);
 putchar(10);
 return;
}


1.6.主函数:

int main()//主函数
{
 pnode L;
 initlink(&L);
 createlink(L);
 traverselink(L);
 insert_element(L);
 traverselink(L);
 delete_element(L);
 traverselink(L);
 insert(L);
 traverselink(L);
 deletes(L);
 traverselink(L);
 return 0;
}

2.循环双链表:

  1. 1.函数声明:
#include<stdio.h> #include<stdlib.h> typedef struct node
{
 int date;
 struct node *next;
}node,*pnode;
/* void initlink(pnode *L);//初始化链表 void createlink(pnode L);//创建链表 void traverselink(pnode L);//遍历链表 pnode get_element(pnode L,int i,pnode *pre);//获取链表中第i节点及其前驱节点 void insert_element(pnode L);//在特定位置插入新节点 void delete_element(pnode L);//删除特定位置节点 pnode get(pnode L,int val,pnode *pre);//获取特定元素节点 void insert(pnode L);//在特定元素之前插入元素 void deletes(pnode L);//删除特定元素节点 int main();//主函数 */

2.2.初始化、创建链表:

void initlink(pnode * L)
{
 *L=(pnode)malloc(sizeof(node)); if(!*L)
 {
  printf("内存分配失败!\n");
  exit(-1);
 }
 (*L)->next=NULL;
 (*L)->previous=*L;
 return;
}

void createlink(pnode L)
{
 pnode p,q;
    int len,i;
 p=L;
 printf("请输入创建链表长度len:\n");
 scanf("%d",&len);
 putchar(10);
 for(i=0;i<len;i++)
 {
  q=(pnode)malloc(sizeof(node)); if(!q)
  {
      printf("内存分配失败!\n");
      exit(-1);
  }
  printf("请输入初始化元素:\n");
  scanf("%d",&q->date);
  q->next=p->next;
  q->previous=p;
  p->next=q;
  p=q;
 }
 putchar(10);
 return;
}

2.3.遍历函数:

void traverselink(pnode L)
{
 pnode h=L->next; while(h!=NULL)
 {
  printf("%d\n",h->date);
  h=h->next;
 }
 putchar(10);
 return;
}


2.4.对链表中特定位置进行增删操作:

pnode get_element(pnode L,int i)
{
 pnode p;
 int k;
 p=L;
 k=0; while(p!=NULL && k<i)
 {
  p=p->next;
  k++;
 }
 return p;
}

void insert_element(pnode L)
{
 pnode h,k;
 int i;
 k=(pnode)malloc(sizeof(node)); if(!k)
 {
  printf("内存分配失败!\n");
  exit(-1);
 }
 printf("请输入插入元素的位置i及插入的元素:\n");
 scanf("%d %d",&i,&k->date);
 h=get_element(L,i); if(!h)
 {
  printf("i值有误\n");
  exit(-1);
 }
 k->next=h;
 k->previous=h->previous;
 h->previous->next=k;
 h->previous=k;
 putchar(10);
 return;
}

void delete_element(pnode L)
{
 pnode h;
 int i;
 printf("请输入要删除元素在链表中的位置i:\n");
 scanf("%d",&i);
 putchar(10);
 h=get_element(L,i); if(!h)
 {
  printf("i值有误\n");
  exit(-1);
 }
 printf("删除的元素为:%d\n",h->date);
 h->previous->next=h->next;
 h->next->previous=h->previous;
 free(h);
 putchar(10);
 return;
}


2.5.对链表中特定元素进行增删操作:

pnode get(pnode L,int val)
{
 pnode p;
 p=L->next; while(p!=NULL && p->date!=val)
 {
        p=p->next;
 }
    return p;
}

void insert(pnode L)
{
 pnode k,h;
 int val;
 k=(pnode)malloc(sizeof(node)); if(!k)
 {
  printf("内存分配失败!\n");
  exit(-1);
 }
 printf("请输入要插入链表中元素val及插入的元素:\n");
 scanf("%d %d",&val,&k->date);
 putchar(10);
 h=get(L,val); if(!h)
 {
  printf("元素不存在\n");
  exit(-1);
 }
 k->next=h;
 k->previous=h->previous;
 h->previous->next=k;
 h->previous=k;
 putchar(10);
 return;
}

void deletes(pnode L)
{
 pnode h;
 int val;
 printf("请输入要删除元素val:\n");
 scanf("%d",&val);
 putchar(10);
 h=get(L,val); if(!h)
 {
  printf("i值有误\n");
  exit(-1);
 }
 h->previous->next=h->next;
 h->next->previous=h->previous;
 free(h);
 putchar(10);
 return;
}


2.6.主函数:

int main()
{
 pnode L;
 initlink(&L);
 createlink(L);
 traverselink(L);
 insert_element(L);
 traverselink(L);
 delete_element(L);
 traverselink(L);
 insert(L);
 traverselink(L);
 deletes(L);
 traverselink(L);
 return 0;
}

代码到此就全部结束啦,如果你还不过瘾的话,我这有小小的推荐:

C语言案例系列:
C语言小案例:学生管理系统1.0版
C语言小案例:登录界面

数据结构基础系列:
撕烂数据爆锤算法:单链表
撕烂数据爆锤算法:内排序之插入算法

前端案例系列:
前端小案例:登录页面

感谢您的支持!
同是天涯码字猿
共勉 共勉 ~ ~