C语言 单向链表 循环链表操作

循环链表

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define ERROR 0
#define OK 1
typedef int EleType;
/*
循环链表的结构和单链表结构一样,不过对于单链表,每个结点只存储了向后的指针,
到了尾标志就停止了向后链的操作,这样知道某个结点却无法找到它的前驱结点。
将单链表中的终端点的指针由空指针改为指向头结点,就使整个单链表形成一个环,
这种头尾相接的单链表称为循环单链表,简称循环链表。
*/
typedef struct CLinkNode
{
	EleType data;
	struct CLinkNode *next;
}CLinkNode,*CLinkList;
 
/*
初始化循环链表
*/
int InitCLinkList(CLinkList *list)
{
	if (list == NULL)
	{
		return ERROR;
	}
 
	int data = 0;
	CLinkNode* target = NULL;
	CLinkNode* head_node = NULL;
	printf("请输入结点数据,0代表结束初始化:\n");
	//这里采用用户控制台输入数据,你也可以随机生成数据进行初始化
	while (1)
	{
		scanf("%d", &data);
		//fflush(stdin);
		if (data == 0)
		{
			//退出循环标志,用户输入0 表示结束输入数据
			break;
		}
 
		/*
		判断初始化的链表有没有结点
		没有结点 先创建头结点 然后插入数据
		有结点 将结点用尾插法插入到链表中
		最后 尾结点的 指针域 指向头结点 这样形成一个环
		*/
		if (*list == NULL)
		{
			CLinkNode* head= (CLinkNode*)malloc(sizeof(CLinkNode));
			//分配结点空间失败
			if (head == NULL)
			{
				exit(0);
			}
 
			*list = head;//链表指向头结点
 
			CLinkNode* node = (CLinkNode*)malloc(sizeof(CLinkNode));
			if (node == NULL)
			{
				exit(0);
			}
			node->data = data;
			node->next = head;
			head->next = node;
		}
		else
		{
			//如果循环链表不为空 链尾部插入数据
			//通过循环 找到尾结点,怎样判断是否是尾结点?当结点的指针域指向头结点时为尾结点,这样才能形成环嘛
			//循环结束后target 指向尾结点
			//for 循环下好好理解下!target初始化为第一个结点指针
			for (target = (*list)->next; target->next != *list; target = target->next);
			head_node = target->next;
 
			CLinkNode* node = (CLinkNode*)malloc(sizeof(CLinkNode));
			if (node == NULL)
			{
				exit(0);
			}
			node->data = data;
			node->next = head_node;
 
			target->next = node;//将新结点插入尾部
		}
 
	}
	return OK;
}
/*
往链表指定位置插入数据
list 循环链表
loc 第loc位置插入元素,loc 从1 开始计数
data 插入元素的数据域
*/
int InsertCLinkNode(CLinkList list,int loc, EleType data)
{
	if (list == NULL || loc < 1)
		return ERROR;
	/*
	循环目的:找到第loc-1位置结点
	*/
	int i = 1;// 按人类的读法 i表示第i个位置 和 loc 表达意思一致
	CLinkNode* node = list;//刚开始node指向头结点
	while (node->next!=list && i < loc)
	{
		node = node->next;
		i++;
	}
	/*
	这里while循环比较难理解,我们拿 3个元素循环链表 来讲解
	loc = 1 时 往第1个位置插入元素
	不进入循环 node 指向头结点 i == loc == 1 插入合法
	loc = 2 时
	node 指向 第1个结点,i = 2 跳出循环
	
	loc = 3 时
	node 指向 第1个结点,i = 2 循环继续
	node 指向 第2个结点,i = 3 跳出循环
	loc = 4 时 注意:如果有3个元素 往第4位置插入元素 是合法!等于往链表尾部插入元素。 
	node 指向 第1个结点,i = 2 循环继续
	node 指向 第2个结点,i = 3 循环继续
	node 指向 第3个结点,i = 4 跳出继续
	
	循环结束时 i==loc 才合法! 此时node 指向 第 loc-1 位置的结点
	将 新结点的指针域 指向 第loc-1位置的后继结点
	将 第loc-1位置的指针域 指向 新结点,这样新结点就插入到 循环链表的 第loc位置了!
	*/
 
	/*
	循环结束时 i==loc 才合法! 此时node 指向 第 loc-1 位置的结点
	将 新结点的指针域 指向 第loc-1位置的后继结点
	将 第loc-1位置的指针域 指向 新结点,这样新结点就插入到 循环链表的 第loc位置了!
	*/
	if (i == loc)
	{
		CLinkNode* new_node = (CLinkNode*)malloc(sizeof(CLinkNode));
		if (new_node == NULL)
		{
			exit(0);
		}
		new_node->data = data;
		new_node->next = node->next;//新结点指针域 指向前驱结点的后继结点
		node->next = new_node;//将新结点加入链表
	}
	else
	{
		return	ERROR;
	}
 
	return OK;
}
/*
删除指定结点,通过指针返回删除结点的数据
*/
int DelCLinkNode(CLinkList list,int loc, EleType* data)
{
	if (list == NULL || loc < 1)
		return ERROR;
	/*
	循环目的:找到第loc-1位置结点
	*/
	int i = 1;// 按人类的读法 i表示第i个位置 和 loc 表达意思一致
	CLinkNode* node = list;//刚开始node指向头结点
	while (node->next != list && i < loc)
	{
		node = node->next;
		i++;
	}
	//循环结束 node 指向 loc-1 位置 且 node 不能为尾结点,为什么不能为尾结点?因为不能删除 位置上没有元素的结点!
	if (i == loc && node->next != list)
	{
		CLinkNode* del_node = node->next;//第loc 位置结点
		*data = del_node->data;//返回删除结点的数据域
 
		node->next = del_node->next;// 删除结点的 前驱结点 指向删除结点的 后继结点,这样删除位置的结点就不在链表中了
		free(del_node);//释放空间
 
	}
	return OK;
}
/*
展示循环链表元素
*/
int ShowCLinkList(CLinkList list)
{
	if (list == NULL)
	{
		return ERROR;
	}
	CLinkNode* target = NULL;
	printf("--------循环链表元素------\n");
	for (target = list->next; target != list; target = target->next)
		printf("%d \t",target->data);
	printf("\n");
	return OK;
}
/*
获取链表元素个数
*/
int LengthCLinkList(CLinkList list)
{
	if (list == NULL)
	{
		return ERROR;
	}
	CLinkNode* target = NULL;
	int length = 0;
	for (target = list->next; target != list; target = target->next)
		length++;
	printf("循环链表元素个数:%d\n", length);
	return OK;
}
/*
获取根据数据获取结点的位置
*/
int IndexCLinkList(CLinkList list,int data)
{
	if (list == NULL)
	{
		return ERROR;
	}
	CLinkNode* target = NULL;
	int length = 0;
	int index = -1;
	for (target = list->next; target != list; target = target->next)
	{
		length++;
		if (target->data == data)
		{
			index = length;
		}
	}
	if (index == -1)
	{
		printf("数据%d在循环链表中不存在\n", data);
	}
	else
	{
		printf("数据%d在第%d个位置\n", data, index);
 
	}
	return index;
}
/*
获取第i个结点的数据内容
*/
int IndexOfCLinkList(CLinkList list, int index)
{
	if (list == NULL || index < 1)
	{
		return ERROR;
	}
	CLinkNode* target = NULL;
	int length = 0;
	int data = -1;
	for (target = list->next; target != list; target = target->next)
	{
		length++;
		if (length == index)
		{
			data = target->data;
		}
	}
	if (index > length)
	{
		printf("第%d个位置结点不存在\n", index);
	}
	else
	{
		printf("第%d个位置的数据:%d\n", index,data);
	}
	return data;
}
int main(int argc, char *argv[])
{
	int flag = 0;
	CLinkList list = NULL;
	while (1)
	{
		printf("===============循环链表功能菜单===========\n");
		printf("===============1、初始化循环链表==========\n");
		printf("===============2、插入元素================\n");
		printf("===============3、删除元素================\n");
		printf("===============4、展示元素================\n");
		printf("===============5、循环链表元素个数========\n");
		printf("===============6、根据数据查询结点位置====\n");
		printf("===============7、根据位置查询结点数据====\n");
		printf("===============0、退出菜单================\n");
		scanf("%d", &flag);
		//fflush(stdin);
		if (flag == 0)
			break;
		if (flag == 1)
		{
			list = NULL;
			InitCLinkList(&list);
			ShowCLinkList(list);
		}
		else if(flag == 2)
		{
			int loc = 0;
			int data = 0;
			printf("请输入插入元素的位置和数据:\n");
			scanf("%d", &loc);
			scanf("%d", &data);
			InsertCLinkNode(list, loc, data);
			ShowCLinkList(list);
		}
		else if (flag == 3)
		{
			int loc = 0;
			int data = 0;
			printf("请输入删除元素的位置:\n");
			scanf("%d", &loc);
			DelCLinkNode(list, loc, &data);
			ShowCLinkList(list);
		}
		else if (flag == 4)
		{
			ShowCLinkList(list);
		}
		else if (flag == 5)
		{
			LengthCLinkList(list);
		}
		else if (flag == 6)
		{
			int loc = 0;
			printf("请输入查找元素的位置:\n");
			scanf("%d", &loc);
			IndexOfCLinkList(list,loc);
		}
		else if (flag == 7)
		{
			int data = 0;
			printf("请输入查找元素的数据:\n");
			scanf("%d", &data);
			IndexCLinkList(list, data);
		}
	}
	return 0;
}

一、头文件linklist.h

//带头节点的链表的基本操作

#ifndef _LINKLIST_H
#define _LINKLIST_H

#define TRUE 1
#define FALSE 0

typedef  int ElemType;

/*
*定义单向链表节点数据结构
*此处要修改
*/
typedef struct node
{
    ElemType data;
    struct node *next;
}linknode, *linklist;

/*对链表操作的接口*/

/*****************单向带头节点的链表操作API********************/

/*创建链表头,返回一个链表指针*/
linklist create_linklist_head(void);

/*清除链表所以数据,并释放内存,传参:链表头*/
void clear_linklist(linklist head);

/*计算返回链表的节点数,传参:链表头,不计算链表头*/
int length_linklist(linklist head);

/*判断链表是否为空链表,传参:链表头,返回TRUE为空*/
int is_empty(linklist head);

/*返回这条数据在链表中节点的位置*/
int locate_linklist(linklist head, ElemType xdata);

/*获取第i个节点的数据,到*ret中*/
int get_linklist(linklist head, int i, ElemType *ret);

/*向链表中的i个节点后面插入linknode结构体的一条数据*/
int insert_linklist(linklist head, ElemType xdata, int i);

/*头插法使链表倒置*/
void reverse_linklist(linklist head);

/*带入两个链表头,合并为一个链表,头1为新链表头,释放头2,flag = 0 遇到相同元素,插入一个即可*/
int merge_linklist(linklist head1,linklist head2,int flag);

/*按照元素大小进行排序,head1为排序后的链表头,head2为要排序的链表头*/
int sort_linklist(linklist head1,linklist head2 );

/*合并两个有序链表组成一个新的有序链表(从小到大),头1为新链表头,释放头2,flag = 0 遇到相同元素,插入一个即可*/
/*head1为排序后的链表头,head2为要排序的链表头1,head2为要排序的链表头1*/
int sort_merge_linklist(linklist head1,linklist head2,linklist head3,int flag);

/*删除第i个节点的数据,传参 :链表头,节点i,返回true成功删除*/
int delete_linklist(linklist head, int i);

/*在链表中查找数据为xdata的结构体,并删除,返回删除的节点最后位置,*i中保存删除的条数*/
int delete_linklist_value(linklist head, ElemType xdata , int *i);

/*显示整条链表的数据,传参:链表头*/
void display_linklist(linklist head);

/*显示第i个节点的数据*/
int display_onelinklist(linklist head , int i);

/*显示第i个节点到第j个节点的数据*/
int display_betweenlinklist(linklist head , int i , int j);

/*******判断是否为循环链表及单链表转换成循环链表******************/
/*判断是否为循环链表,返回true是*/
int is_cyclelinklist(linklist head); 

/*将单向链表转换成循环链表*/
int switch_is_cyclelinklist(linklist head);


/******单向循环链表操作******************************************/
/*调用上面switch_is_cyclelist()函数可将单向链表转化为单向循环链表*/

linklist create_cyclelinklist_head(void);

/*清除循环链表所有数据,并释放内存,传参:链表头指针*/
void clear_cyclelinklist(linklist head);

/*计算返回循环链表的节点数,传参:链表头*/
int length_cyclelinklist(linklist head);

/*判断循环链表是否为空链表,传参:链表头,返回TRUE为空*/
int cyclelinklistempty(linklist head);

/*返回这条数据在循环链表中节点的位置*/
int locate_cyclelinklist(linklist head, ElemType xdata);

/*获取第i个节点的数据,到*ret中*/
int get_cyclelinklist(linklist head, int i, ElemType *ret);

/*向链表中的i个节点后面插入linknode结构体的一条数据*/
int insert_cyclelinklist(linklist head, ElemType xdata, int i); //插在第i个节点后面

/*删除第i个节点的数据,传参 :链表头,节点i,返回true成功删除*/
int delete_cyclelinklist(linklist head, int i);

/*头插法使链表倒置*/
void reverse_cyclelinklist(linklist head); //头插法使循环链表倒置

/*显示整条链表的数据,传参:链表头*/
void display_cyclelinklist(linklist head);

/*将循环链表转换成单向链表*/
int switch_is_linklist(linklist head);

#endif
 /* _LINKLIST_H */

二、函数实现C文件linklist.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "linklist.h"

/*创建链表头,返回一个链表指针*/
linklist create_linklist_head(void)
{
    linklist head = (linklist)malloc(sizeof(linknode));
    if (head == NULL)
    {
        return NULL;
    }
/*根据数据结构不同,这里需要修改*/
    head->data = -1;
    head->next = NULL;
    return head;
}

/*清除链表所以数据,并释放内存,传参:链表头*/
void clear_linklist(linklist head)
{
    linklist q = head->next;
    while (q)
    {
        head->next = q->next;
        free(q);
        q = head->next;
    }
free(head);//释放掉头
head = NULL;
}

/*计算返回链表的节点数,传参:链表头,不计算链表头*/
int length_linklist(linklist head)
{
    int count = 0;
    linklist p = head->next;
    while (p)
    {
        count++;
        p = p->next;
    }
    return count;
}

/*判断链表是否为空链表,传参:链表头,返回TRUE为空*/
int is_empty(linklist head)
{
    return head->next == NULL ? TRUE : FALSE; 
}

/*返回这条数据在链表中节点的位置*/
int locate_linklist(linklist head, ElemType xdata)
{
    int count = 0;
    linklist p = head->next;
    while (p)
    {
/*根据数据结构不同,这里需要修改*/
        if (p->data == xdata)
        {
            return count+1;
        }
        p = p->next;
        count++;
    }

    return 0;
}

/*获取第i个节点的数据,到*ret中*/
int get_linklist(linklist head, int i, ElemType *ret)
{
    if (i < 0 || i > length_linklist(head))
    {
        printf("get_linklist failed,node less %d is wrong!\n", i);
        return FALSE;
    }

    linklist p = head;
    int j;
    for (j = 0; j < i; j++)
    {
        p = p->next;
    }
*ret = p->data;

    return TRUE;
}

/*向链表中的i个节点后面插入linknode结构体的一条数据*/
int insert_linklist(linklist head, ElemType xdata, int i) //插在第i个节点后面
{
    if (i < 0 || i > length_linklist(head)+1)
    {
        printf("insert_linklist failed,node under %d \n", i);
        return FALSE;
    }

    linklist q = (linklist)malloc(sizeof(linknode));
q->data = xdata;
    q->next = NULL;

    int j;
    linklist p = head;
    for (j = 0; j < i; j++) 
    {
        p = p->next;
    }
    q->next = p->next;
    p->next = q;

    return TRUE;
}

/*删除第i个节点的数据,传参 :链表头,节点i,返回true成功删除*/
int delete_linklist(linklist head, int i)
{
    if (i < 0 || i > length_linklist(head))
    {
        printf("delete_linklist failed,node under %d\n", i);
        return FALSE;
    }

    linklist p = head, q = head;
    int j;
    for (j = 0; j < i-1; j++)
    {
        p = p->next;
    }
    q = p->next;
    p->next = q->next;
    free(q);
    q = NULL;

    return TRUE;
}

/*在链表中查找数据为xdata的结构体,并删除,返回删除的节点到i中*/
int delete_linklist_value(linklist head, ElemType xdata,int *i)
{
    int count = 0;
    linklist p = head, q = head;
    while (p)
    {
/*根据数据结构不同,这里需要修改*/
        if (p->data == xdata)
        {
 int j;
for (j = 0; j < count-1; j++)
{
q = q->next;
}
q->next = p->next;
free(p);
(*i)++;
        }
        p = p->next;
        count++;
    }
    return count;
}

/*头插法使链表倒置*/
void reverse_linklist(linklist head) //头插法使链表倒置
{
    linklist q, p =  head->next;
    head->next = NULL;

    while (p)
    {
        q = p->next;
        p->next = head->next;
        head->next = p;
        p = q;
    }
}

/*带入两个链表头,合并为一个链表,头1为新链表头,释放头2,flag = 0 遇到相同元素,插入一个即可*/
int merge_linklist(linklist head1,linklist head2,int flag)
{
int x = length_linklist(head1);
int y = length_linklist(head2);
if((x<=0) | (y<=0)) return -1;
if(flag == 1){
linklist p = head1->next;
while (p->next)
{
p = p->next;
}
p->next = head2->next;
free(head2);
return 1;
}else{
int i;
ElemType e;
for(i = 1;i <= y ;i++){
get_linklist(head2,i,&e);
if(!locate_linklist(head1,e))
insert_linklist(head1,e,x++);
}
clear_linklist(head2);
return 1;
}
}

/*合并两个有序链表组成一个新的有序链表(从小到大),头1为新链表头,释放头2,flag = 0 遇到相同元素,插入一个即可*/
/*head1为排序后的链表头,head2为要排序的链表头1,head2为要排序的链表头1*/
int sort_merge_linklist(linklist head1,linklist head2,linklist head3,int flag)
{
int x = length_linklist(head2);
int y = length_linklist(head3);
if((x<=0) | (y<=0)) return -1;

int i = 1, j = 1, k = 0;
ElemType e1,e2;
while((i <= x) && (j <= y)){
get_linklist(head2,i,&e1);
get_linklist(head3,j,&e2);
if(e1 <= e2){
if(flag == 1){
insert_linklist(head1,e1,k++);
i++;
}else{
if(e1 == e2){
insert_linklist(head1,e1,k++);
i++;
j++;
}
}
}else{
insert_linklist(head1,e2,k++);
j++;
}
}
while( i<= x){
get_linklist(head2,i++,&e1);
insert_linklist(head1,e1,k++);
}
while( j<= y){
get_linklist(head3,j++,&e1);
insert_linklist(head1,e1,k++);
}
clear_linklist(head2);
clear_linklist(head3);
return 1;
}
/*按照元素大小进行排序,head1为排序后的链表头,head2为要排序的链表头*/
int sort_linklist(linklist head1,linklist head2 )
{
int x;
int i,j,z,dest = 0;
ElemType max,min,e;
while(!is_empty(head2)){
x = length_linklist(head2);
get_linklist(head2,1,&max);
for(i = 2 ; i <= x ; i++){
get_linklist(head2,i,&min);
if(max < min)
{
e = min;
min = max;
max = e;
}
}
insert_linklist(head1,max,dest++);
delete_linklist_value(head2,max,&z);
}
free(head2);
return 1;
}
/*显示整个链表*/
void display_linklist(linklist head)
{
    linklist p = head->next;
printf("display_linklist :");
    while (p)
    {
/*根据数据结构不同,这里需要修改*/
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

/*显示第i个节点的数据*/
int display_onelinklist(linklist head , int i)
{
if (i < 0 || i > length_linklist(head))
    {
        printf("display_onelinklist failed,node under %d\n", i);
        return FALSE;
    }

int j;
    linklist p = head;
printf("display_onelinklist %d :",i);
    for (j = 0; j < i; j++) 
    {
        p = p->next;
    }
/*根据数据结构不同,这里需要修改*/
    printf("  %d  \n", p->data);
    return TRUE;

}

/*显示第i个节点到第j个节点的数据*/
int display_betweenlinklist(linklist head , int i , int j)
{
if (i < 0 || i > length_linklist(head))
    {
        printf("display_betweenlinklist failed,node under %d\n", i);
        return FALSE;
    }
if (j < 0 || j > length_linklist(head))
    {
        printf("display_betweenlinklist failed,node under %d\n", j);
        return FALSE;
    }
    int x;
    linklist p = head;
printf("display_betweenlinklist %d to %d :",i,j);
    for (x = 0; x < i; x++) 
    {
        p = p->next;
    }
for(;x <= j ; x++)
{
/*根据数据结构不同,这里需要修改*/
        printf("%d ", p->data);
        p = p->next;
}
printf("\n");
    return TRUE;

}

/****************判断是否为循环链表及单链表转换成循环链表**********/
/*判断是否为循环链表,*/
int is_cyclelinklist(linklist head)
{
    linklist p1, p2;
    p1 = p2 = head->next;
    while(p2)
    {
        p2 = p2->next;
        if(p1 == p2)
        {
            printf("There is a cyclelinklist!\n");
            return TRUE;
        }   
    }
    return FALSE;
}

/*将单向链表转换成循环链表*/
int switch_is_cyclelinklist(linklist head)
{
linklist p = head->next;

while (p->next)
    {
        p = p->next;
    }
p->next = head->next ;
    return TRUE;
}
/******单向循环链表操作******************************************/
/*调用上面switch_is_cyclelist()函数可将单向链表转化为单向循环链表*/
linklist create_cyclelinklist_head(void)
{
    linklist head = (linklist)malloc(sizeof(linknode));
    if (head == NULL)
    {
        return NULL;
    }
/*根据数据结构不同,这里需要修改*/
    head->data = -1;
    head->next = NULL;
    return head;
}
/*清除循环链表所有数据,并释放内存,传参:链表头指针*/
void clear_cyclelinklist(linklist head)
{
    linklist q = head->next;
linklist p; 
if(head->next == NULL){
printf("clear_cyclelinklist fail : cyclelinklist empty\n");
return ;
}

    do{
        p = q->next;
        free(q);
        q = p;
    }while (q != head->next);
    free(head); 
}

/*计算返回循环链表的节点数,传参:链表头*/
int length_cyclelinklist(linklist head)
{
    int count = 0;
    linklist p = head->next;
if(head->next == NULL){
printf("length_cyclelinklist fail : cyclelinklist empty\n");
return -1;
}

    do{
        p = p->next;
count++;
    }while (p != head->next);
    return count;
}

/*判断循环链表是否为空链表,传参:链表头,返回TRUE为空*/
int cyclelinklistempty(linklist head)
{
    return head->next == NULL ? TRUE : FALSE; 
}

/*返回这条数据在循环链表中节点的位置*/
int locate_cyclelinklist(linklist head, ElemType xdata)
{
    int count = 1;
    linklist p = head->next;
if(head->next == NULL){
printf("locate_cyclelinklist fail : cyclelinklist empty\n");
return -1;
}
do{
if (p->data == xdata)
        {
            return count;
        }
        p = p->next;
count++;
    }while(p != head->next);

    return 0;
}

/*获取第i个节点的数据,到*ret中*/
int get_cyclelinklist(linklist head, int i, ElemType *ret)
{
    if (i < 0 || i > length_cyclelinklist(head))
    {
        printf("i=%d is wrong!\n", i);
        return FALSE;
    }

    linklist p = head->next;
    int j;
    for (j = 1; j < i; j++)
    {
        p = p->next;
    }
    *ret = p->data;

    return TRUE;
}

/*向链表中的i个节点后面插入linknode结构体的一条数据*/
int insert_cyclelinklist(linklist head, ElemType xdata, int i) //插在第i个节点后面
{
    if (i < 0 || i > length_cyclelinklist(head)+1)
    {
        printf("i=%d is wrong!\n", i);
        return FALSE;
    }

    linklist q = (linklist)malloc(sizeof(linknode));
q->data = xdata;
    q->next = NULL;

    if (head->next == NULL)
    {
        head->next = q;
        q->next = q;
    }
    else
    {
        if (i == 0)//插在第一个结点前面
        {
            linklist p = head->next;
            while(p->next != head->next)
            {
                p = p->next;
            }
            q->next = head->next;
            p->next = q;
            head->next = q;
        }
        else
        {
            int j;
            linklist p = head->next;
            for (j = 0; j < i; j++) 
            {
                p = p->next;
            }
            q->next = p->next;
            p->next = q;
        }
    }
    return TRUE;
}

/*删除第i个节点的数据,传参 :链表头,节点i,返回true成功删除*/
int delete_cyclelinklist(linklist head, int i)
{
    if (i < 0 || i > length_cyclelinklist(head))
    {
        printf("i=%d is wrong!\n", i);
        return FALSE;
    }

    linklist p = head->next;
linklist q = head->next;//q指向待删除节点,p找位置

    if (i == 1)
    {
        while(p->next != head->next)//指向最后一个节点
        {
            p = p->next;
        }
        p->next = q->next;
        head->next = q->next;
        free(q);
        q = NULL;
    }
    else
    {
        int j;
        for (j = 1; j < i-1; j++)
        {
            p = p->next;
        }
        q = p->next;
        p->next = q->next;
        free(q);
        q = NULL;
    }

    return TRUE;
}

/*头插法使链表倒置*/
void reverse_cyclelinklist(linklist head) //头插法使循环链表倒置
{
    linklist  q =  head->next; //q指向待插入的节点,p遍历
    linklist  p =  head->next;
if(head->next == NULL){
printf("reverse_cyclelinklist fail : cyclelinklist empty\n");
return ;
}
    while (q->next != q)
    {
        q->next = head->next;
        head->next = q;
        q = p;
        p = p->next;
    }
    p->next = head->next;
}

/*显示整条链表的数据,传参:链表头*/
void display_cyclelinklist(linklist head)
{
    linklist p = head->next;
if(head->next == NULL){
printf("display_cyclelinklist fail : cyclelinklist empty\n");
return ;
}
printf("display_cyclelinklist:");
do{
printf("%d ", p->data);
        p = p->next;
    }while (p != head->next);
printf("\n");
}

/*将循环链表转换成单向链表*/
int switch_is_linklist(linklist head)
{
if(is_cyclelinklist(head))
printf("switch_is_linklist--------------\n");
if(head->next == NULL){
printf("switch_is_linklist fail : cyclelinklist empty\n");
return 0;
}
linklist p = head->next;
while(p->next != head->next)
p = p->next;
p->next = NULL;
return TRUE;
}



int main(int argc, const char *argv[])
{
    linklist head = create_linklist_head();

    int i;

    for (i = 5; i <=10; i++) 
    {
        insert_linklist(head, i, 0);
    }
    insert_linklist(head, 12, 6);
insert_linklist(head, 13, 7);
    printf("lenght:%d\n",length_linklist(head));  
    display_linklist(head);

linklist w = create_linklist_head();
sort_linklist(w,head);
 reverse_linklist(w);
    printf("lenght:%d\n",length_linklist(w));  
    display_linklist(w);
linklist h = create_linklist_head();
for (i = 2; i <=10; i++) 
    {
        insert_linklist(h, i, 0);
    }
 reverse_linklist(h);
printf("lenght:%d\n",length_linklist(h));  
    display_linklist(h);
linklist z = create_linklist_head();
sort_merge_linklist(z,w,h,1);
//merge_linklist(w,h,0);
printf("lenght:%d\n",length_linklist(z));  
    display_linklist(z);
if(!is_cyclelinklist(z))
{
printf(" no cycle\n");
}


display_onelinklist( z , 2);


display_betweenlinklist(z,2,4);

   switch_is_cyclelinklist( z);

   if(!is_cyclelinklist(z))
{
printf("no cycle\n");
}
else
{
printf("cycle\n");
}
display_cyclelinklist(z);
printf("length:%d\n",length_cyclelinklist(z));
insert_cyclelinklist(z, 1, 0);
insert_cyclelinklist(z, 120, 1);
printf("length:%d\n",length_cyclelinklist(z));
display_cyclelinklist(z);
//reverse_cyclelinklist(z);
delete_cyclelinklist(z,1);
display_cyclelinklist(z);
ElemType a;
get_cyclelinklist(z,1,&a);
printf("a:%d\n",a);
display_cyclelinklist(z);
printf("13   ==%d\n",locate_cyclelinklist(z,13));
switch_is_linklist(z);
display_linklist(z);
/*
    printf("return 5 locate %d\n",locate_linklist( head, 5));


    ElemType p;
    get_linklist(head, 3, &p);
    printf("get %d node:%d\n",3,p);

    int c;
    delete_linklist_value(head, p ,&c);

display_linklist(head);

    delete_linklist(head, 2);

    display_linklist(head);

    reverse_linklist(head);

    display_linklist(head);

    reverse_linklist(head);

    display_linklist(head);

    if(!is_cyclelist(head))
{
printf(" no cycle\n");
}


display_onelinklist( head , 2);


display_betweenlinklist(head,2,4);

   switch_is_cyclelist( head);

   if(!is_cyclelist(head))
{
printf("no cycle\n");
}
else
{
printf("cycle\n");
}
    //clear_linklist(head);
printf("clear:");
   // display_linklist(head);

    return 0;*/
}
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值