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

一、头文件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;*/
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值