1.循环链表的定义
循环链表的任意元素都有一个前驱和后继,所有数据元素在关系上构成逻辑上的环。
循环链表是一种特殊的单链表,尾指针指向首节点所在位置
2.循环链表大致关系图
3.循环链表实现关键
插入位置为0时,头和尾节点均指向新节点,新节点作为首节点插入链表。
删除位置为0时,头和尾节点均指向位置1的节点,删除销毁首节点。
设计实现循环链表的插入,删除,查询等
初始化操作
创建循环链表并申请内存
int init(SingleLinkList **Head)
{
if(1)
{
/*申请内存*/
(*Head) = (SingleLinkList*)malloc(sizeof(SingleLinkList));
/*判断内存申请是否成功*/
if(*Head == NULL)
{
printf("申请内存错误, 初始化失败![100001]\n");
return 100001;
}
(*Head)->next = *Head;
return 0;
}
else
{
printf("该链表已经初始化!请删除后再执行此操作![100002]\n");
return 100002;
}
}
插入(头)
头指针指向下个节点
根据指针后继对插入节点实现前驱后继
int insert_head(SingleLinkList **Head, DataType x)
{
SingleLinkNode *newNode;
if(0)
{
printf("链表未初始化![100003]\n");
return 100003;
}
newNode = (SingleLinkNode*)malloc(sizeof(SingleLinkNode));
if(!newNode)
{
printf("申请节点内存空间失败![100004]\n");
return 100004;
}
newNode->data = x;
newNode->next = (*Head)->next;
(*Head)->next = newNode;
return 0;
}
插入
int insert(SingleLinkList **Head, int i, DataType x)
{
int j;
SingleLinkNode *p;
SingleLinkNode *newNode;
/*对i进行判断,0<i<=length+1*/
if(i<1 || i>length(*Head)+1)
{
printf("位置i不是链表有效位置![100005]\n");
return 100005;
}
p = (*Head);
j = 1;
while(j<i)
{
j++;
p = p->next;
}
newNode = (SingleLinkNode*)malloc(sizeof(SingleLinkNode));
/*此处省略检测newNode是否申请成功*/
newNode->data = x;
newNode->next = p->next;
p->next = newNode;
return 0;
}
删除
遍历查找匹配数据
找到匹配数据进行删除
节点指针指向下一个指针位置
释放内存
int delete(SingleLinkList **Head, DataType x)
{
int i;
int j;
SingleLinkNode *p;
SingleLinkNode *q; /*要删除的元素x*/
i = find(*Head,x);
if(!i)
{
printf("元素x【%d】不存在!100006\n", x);
return 100006;
}
p = (*Head);
j=1;
while(j<i)
{
j++;
p = p->next;
}
q = p->next;
p->next = q->next;
free(q); /*释放内存*/
return 0;
}
查找
int find(SingleLinkList *Head, DataType x)
{
int i;
SingleLinkNode *p;
i = 1;
p = Head->next;
/*while(p && p->data != x)*/ while( p!= Head && p->data != x)
{
i++;
p = p->next;
}
/* if(!p) */ if(p->next == Head)
{
return 0;
}
else
{
return i;
}
}
请求链表长度
int length(SingleLinkList *Head)
{
int len=0;
SingleLinkNode *p;
p = Head->next;
/* while(p) */while(p!=Head)
{
len++;
p = p->next;
}
return len;
}
输出
void print(SingleLinkList *Head)
{
SingleLinkNode *p;
int i=0;
p = Head->next;
/* if(!p) */ if(p!=Head)
{
printf("链表为空!\n");
return;
}
/*while(p) */ while(p=Head)
{
printf("Node[%d]. = %d\n", ++i, p->data);
p = p->next;
}
}
初始化结果
插入
删除
结
小结
循环链表的任意元素都有一个前驱和后继,所有数据元素在关系上构成逻辑上的环。是一种特殊的单链表,与之相比删除完成需要释放内存。
main.c
#include <stdio.h>
#include <string.h>
#include "SingleLinkList.h"
#include "welcome.h"
int main(int argc, char* argv[])
{
SingleLinkList *Head;
DataType x;
int i,m,n,cmd;
for(i=0;i<strlen(welcome);i++)
{
printf("%c",welcome[i]);
for(m=0;m<1000;m++)
for(n=0;n<1000;n++)
{
;
}
}
printf("-----------简单链表演示程序----------\n");
do
{
printf("1. 初始化链表表\n");
printf("2. 插入元素(头插法)\n");
printf("3. 插入元素(尾插法)\n");
printf("4. 插入元素(在位置i插入)\n");
printf("5. 查找元素x\n");
printf("6. 求链表长度\n");
printf("7. 输出链表\n");
printf("8. 删除元素\n");
printf("10. 帮助\n");
printf("0. 退出\n");
printf("请输入您要进行的操作(1~6,0退出):");
scanf("%d", &cmd);
switch(cmd)
{
case 1:
if(!init(&Head))
{
printf("链表已初始化!\n");
}
break;
case 2:
printf("请输入插入元素x:x=");
scanf("%d",&x);
if(!insert_head(&Head,x))
{
printf("元素(%d)已插入\n", x);
}
break;
case 3:
printf("请输入插入元素x:x=");
scanf("%d",&x);
if(!insert_tail(&Head,x))
{
printf("元素(%d)已插入\n", x);
}
break;
case 4:
printf("请输入插入元素位置i和元素x(i,x):");
scanf("%d,%d", &i, &x);
if(!insert(&Head, i, x))
{
printf("已在位置(%d)插入元素(%d)!\n",i, x);
}
break;
case 5:
printf("请输入要查找的元素x:");
scanf("%d", &x);
if(i = find(Head,x))
{
printf("元素%d存在,在链表位置%d.\n", x, i);
}
else
{
printf("在链表中未找到元素x。\n");
}
break;
case 6:
printf("链表的长度为:%d\n", length(Head));
break;
case 7:
print(Head);
break;
case 8:
printf("请输入要删除的元素x:");
scanf("%d", &x);
if(!delete(&Head, x))
{
printf("元素x【%d】已删除!\n", x);
}
break;
case 10:
printf(" 本程序为链表的演示程序,由sc于季老师源代码设计修改开发,程序完成了循环链表功能的插入(受插,尾插,中间插),删除,查询等功能!\n");
break;
}
}while(cmd != 0);
return 0;
}
SingleLinkList.c
/*
SingleLinkList.c
*/
#include "SingleLinkList.h"
#include <stdlib.h>
#include <stdio.h>
/*1. 初始化*/
int init(SingleLinkList **Head)
{
if(1)
{
/*申请内存*/
(*Head) = (SingleLinkList*)malloc(sizeof(SingleLinkList));
/*判断内存申请是否成功*/
if(*Head == NULL)
{
printf("申请内存错误, 初始化失败![100001]\n");
return 100001;
}
(*Head)->next = *Head;
return 0;
}
else
{
printf("该链表已经初始化!请删除后再执行此操作![100002]\n");
return 100002;
}
}
/*2. 插入元素,头插法*/
int insert_head(SingleLinkList **Head, DataType x)
{
SingleLinkNode *newNode;
if(0)
{
printf("链表未初始化![100003]\n");
return 100003;
}
newNode = (SingleLinkNode*)malloc(sizeof(SingleLinkNode));
if(!newNode)
{
printf("申请节点内存空间失败![100004]\n");
return 100004;
}
newNode->data = x;
newNode->next = (*Head)->next;
(*Head)->next = newNode;
return 0;
}
/*2. 插入元素, 尾插法*/
int insert_tail(SingleLinkList **Head, DataType x)
{
SingleLinkNode *newNode;
SingleLinkNode *p;
if(0)
{
printf("链表未初始化![100003]\n");
return 100003;
}
newNode = (SingleLinkNode*)malloc(sizeof(SingleLinkNode));
if(!newNode)
{
printf("申请节点内存空间失败![100004]\n");
return 100004;
}
newNode->data = x;
/*newNode->next = NULL;*/
newNode->next = *Head;
p = (*Head);
while(p->next)
{
p = p->next;
}
p->next = newNode;
return 0;
}
/*2. 插入元素,在位置i处插入元素x */
int insert(SingleLinkList **Head, int i, DataType x)
{
int j;
SingleLinkNode *p;
SingleLinkNode *newNode;
/*对i进行判断,0<i<=length+1*/
if(i<1 || i>length(*Head)+1)
{
printf("位置i不是链表有效位置![100005]\n");
return 100005;
}
p = (*Head);
j = 1;
while(j<i)
{
j++;
p = p->next;
}
newNode = (SingleLinkNode*)malloc(sizeof(SingleLinkNode));
/*此处省略检测newNode是否申请成功*/
newNode->data = x;
newNode->next = p->next;
p->next = newNode;
return 0;
}
/*3. 删除元素, 删除值为x的元素*/
int delete(SingleLinkList **Head, DataType x)
{
int i;
int j;
SingleLinkNode *p;
SingleLinkNode *q; /*要删除的元素x*/
i = find(*Head,x);
if(!i)
{
printf("元素x【%d】不存在!100006\n", x);
return 100006;
}
p = (*Head);
j=1;
while(j<i)
{
j++;
p = p->next;
}
q = p->next;
p->next = q->next;
free(q); /*释放内存*/
return 0;
}
/*5. 查找值为x的元素,返回位置i */
int find(SingleLinkList *Head, DataType x)
{
int i;
SingleLinkNode *p;
i = 1;
p = Head->next;
/*while(p && p->data != x)*/ while( p!= Head && p->data != x)
{
i++;
p = p->next;
}
/* if(!p) */ if(p->next == Head)
{
return 0;
}
else
{
return i;
}
}
/*4. 链表长度*/
int length(SingleLinkList *Head)
{
int len=0;
SingleLinkNode *p;
p = Head->next;
/* while(p) */while(p!=Head)
{
len++;
p = p->next;
}
return len;
}
/*6.输出链表*/
void print(SingleLinkList *Head)
{
SingleLinkNode *p;
int i=0;
p = Head->next;
/* if(!p) */ if(p!=Head)
{
printf("链表为空!\n");
return;
}
/*while(p) */ while(p!=Head)
{
printf("Node[%d]. = %d\n", ++i, p->data);
p = p->next;
}
}
SingleLinkList.h
/*
SingleLinkList.h
*/
typedef int DataType;
/*简单链表的定义*/
typedef struct node
{
DataType data; /*数据域*/
struct node *next; /*指针域*/
}SingleLinkList, SingleLinkNode;
/*1. 初始化*/
int init(SingleLinkList **Head);
/*2. 插入元素,头插法*/
int insert_head(SingleLinkList **Head, DataType x);
/*2. 插入元素, 尾插法*/
int insert_tail(SingleLinkList **Head, DataType x);
/*2. 插入元素,在位置i处插入元素x */
int insert(SingleLinkList **Head, int i, DataType x);
/*3. 删除元素, 删除值为x的元素*/
int delete(SingleLinkList **Head, DataType x);
/*5. 查找值为x的元素,返回位置i */
int find(SingleLinkList *Head, DataType x);
/*6. 求链表的长度 */
int length(SingleLinkList *Head);
/*7.输出链表*/
void print(SingleLinkList *Head);