C语言链表

C语言链表

list.h

#ifndef  LIST_H
#define  LIST_H

#define OK       1
#define OVERFLOW 0

#define TRUE     1
#define FALSE    2

#define ERROR    0
#define ILLEGAL -1

typedef struct ListNode
{
    int        data;
    struct ListNode *next;
}ListNode;

typedef struct LinkList
{
    ListNode *phead;
    ListNode *pcur;
    int      num;
    struct LinkList *next;
}Node,*LinkList;

int InitList(LinkList *L);//初始化链表,OK表示成功,OVERFLOW表示溢出
int ClearList(LinkList L);//清空链表结点

int CreateListHead(LinkList L,void (*Input)(int *));//头插法创建链表
int CreateListTail(LinkList L,void (*Input)(int *));//尾插法创建链表

int DisplayList(LinkList L,void (*Visit)(int *));

int LengthofList(LinkList L,int *length);//求链表长度

int EmptyList(LinkList L);//释放链表

int Equal(int *value1,int *value2);//比较两个值是否相等,在按值查找中应用

int FindListValue(LinkList L, int *value, int *outposition,int(*Equal)(int *,int *));//按值查找

int FindListOrder(LinkList L, const int position, int * pevalue);//按序查找

int UpdateList(LinkList L, int position, void (*Input)(int *));//更新结点

int InsertList(LinkList L, int position, void (*Input)(int *));//插入结点

int DeleteList(LinkList L, const int position, int *x);//after delete: phead->next = NULL

int SortList(LinkList L);//对单链表排序

#endif






list.c

#include <stdio.h>
#include <stdlib.h>
#include "list.h"

/*****************************************************************************                  
* 函数名称: InitList
* 功能描述: 初始化单链表
* 输入参数: LinkList *L      提供一个链表
* 输出参数: 初始化一个链表
* 返 回 值: OVERFLOW : 初始化失败;OK :初始化成功 
******************************************************************************/
int InitList(LinkList *L)
{
	*L=(LinkList)malloc(sizeof(Node));
	if(NULL == (*L))
	{
		return OVERFLOW;
	}
	else
	{
		(*L)->next = NULL;
	        (*L)->num = 0;
		(*L)->phead = NULL;
		(*L)->pcur = NULL;
        return OK;
	}

}
/*****************************************************************************                  
* 函数名称: CreateListHead
* 功能描述: 头插法创建链表
* 输入参数: LinkList L	                提供链表头指针
	     void (*Input)(int *)	提供结点值的输入函数
* 输出参数: 头插法创建一个单链表
* 返 回 值: OVERFLOW : 创建单链表失败;OK :创建单链表成功 
******************************************************************************/
int CreateListHead(LinkList L,void (*Input)(int *))
{	
	int i;//控制循环
	int value;//结点的值

	int Number;//创建单链表的个数
	printf("请输入单链表的个数:");
	scanf("%d",&Number);	

    for(i = 0; i<Number; i++)
	{
	    ListNode *p = NULL;
	    p = (ListNode*)malloc(sizeof(ListNode));
		printf("请输入第%d节点的值!",i+1);
	    Input(&value);
		
        if(NULL == p)
		{
		  	return OVERFLOW;
		}
		p->data = value;
		p->next = NULL;

	    p->next = L->phead;
	    L->phead = p;
	    L->num++; 
	}
	return OK;	
}

/*****************************************************************************                  
* 函数名称: CreateListHead
* 功能描述: 尾插法创建链表
* 输入参数: LinkList L	                提供链表头指针
	     void (*Input)(int *)	提供结点值的输入函数
* 输出参数: 尾插法创建一个单链表
* 返 回 值: OVERFLOW : 创建单链表失败;OK :创建单链表成功 
******************************************************************************/
int CreateListTail(LinkList L,void (*Input)(int *))//尾插法创建链表
{
	int Number;
	int i;
	int value;
	
	printf("请输入单链表的个数:");
	scanf("%d",&Number);
	

	L->phead = L->pcur;
	L->num = 0;
    for(i=0; i<Number; i++)
	{
		ListNode *p = NULL;
	    p = (ListNode*)malloc(sizeof(ListNode));		

		printf("请输入第%d节点的值!",i+1);
	    Input(&value);
        if(NULL == p)
		{
			return OVERFLOW;
		}
		p->data = value;
		p->next = NULL;
		if(0 == i)//第一个结点
		{
			L->phead = p;
		}
		else//其它结点
		{
			L->pcur->next = p;
		}	
		L->pcur = p;
		L->num++;
	}
	return OK ;
}
/*****************************************************************************                  
* 函数名称: FindListOrder
* 功能描述: 按序号查找结点
* 输入参数: LinkList L	           提供头指针
	     const int position	   提供结点所在位置
             int *pvalue      接受查找到的结点的值
* 输出参数: 按给定的序号查找结点
* 返 回 值: OK : 查找成功;ILLEGAL :查找失败 
******************************************************************************/
int FindListOrder(LinkList L, const int position,int *pvalue)
{
	int counter = 0;
	if(position <1 || position > L->num)
	{
		return ILLEGAL;
	}
	
	L->pcur = L->phead;
	while(NULL != L->pcur)
	{
		counter++;
		if(counter == position)
		{
			*pvalue = L->pcur->data;
			return OK;
		}

		L->pcur = L->pcur->next;
	}
	return OK;
}
/*****************************************************************************                 
* 函数名称: FindListValue
* 功能描述: 按值查找结点
* 输入参数: LinkList L	                  提供链表头指针
	     int *value	          提供要查找的值
	     void (*Input)(int *)	  提供结点值的输入函数
	     int *outposition             接受查找到的结点的位置
* 输出参数: 按给定的值查找结点
* 返 回 值: 返 回 值: OK : 查找成功;ERROR :查找失败 
******************************************************************************/
int FindListValue(LinkList L, int *value, int *outposition,int(*Equal)(int *,int *))
{	
	int count = 1;
	
	L->pcur = L->phead;
	while(NULL != L->pcur)
	{
		if(TRUE == Equal(&L->pcur->data,value)) //由Equal的函数指针进行调用
		{
			*outposition = count;
			return OK;
		}
		count++;
		L->pcur = L->pcur->next;
	}
	return ERROR;
}
/*****************************************************************************                  
* 函数名称: InsertList
* 功能描述: 向链表插入一个新结点
* 输入参数: LinkList L	                  提供链表头指针
	     int position	          提供插入的位置
             void (*Input)(int *)	  提供待插入结点值的输入函数
* 输出参数: 向单链表第position个位置后插入新结点
* 返 回 值: ILLEGAL : 插入位置不合法;OK :插入成功 
******************************************************************************/
int InsertList(LinkList L, int position, void (*Input)(int *))
{
	int counter = 0;
	int value;

	ListNode *p = NULL;
    p = (ListNode*)malloc(sizeof(ListNode));
	
	if(position <0 || position > L->num)
	{
		return ILLEGAL;
	}	

    L->pcur = L->phead;
	while(NULL != L->pcur)
	{
		counter++;
		if(0 == position)
		{	        
			Input(&value);
			p->data = value;
			
			p->next = L->phead;
			L->phead = p;
			L->num++;
			return OK;
		}
		if(counter == position)
		{
			Input(&value);
			p->data = value;

			p->next = L->pcur->next;
			L->pcur->next = p;
			L->num++;
			return OK;
		}
		L->pcur = L->pcur->next;
	}
	return OK;
}
/*****************************************************************************                  
* 函数名称:DeleteList 
* 功能描述:删除结点
* 输入参数:LinkList L 	          提供头指针
	    const int position 	  提供待删除结点的位置
            int *x           提供被删除结点的值
* 输出参数:删除单链表某结点
* 返 回 值:ILLEGAL : 删除位置不合法 OK :删除成功 
******************************************************************************/
int DeleteList(LinkList L, const int position, int *x)
{
	int        i;
	ListNode *ptTemp;
	L->pcur = L->phead;
	ptTemp = L->phead;

	if(position <1 || position > L->num)
	{
		return ILLEGAL;
	}
	if(1 == position)
	{
		*x = L->phead->data;
	    L->phead = L->phead->next;
	    L->num--;
	    free(ptTemp);
	}
    else
	{
		for(i=1; i< position-1; i++)
		{		
	    	L->pcur = L->pcur->next;
	    	ptTemp = L->pcur->next;
		}
	    *x = L->pcur->next->data;
	    L->pcur->next = L->pcur->next->next;
	    L->num--;
	   free(ptTemp);	
    }
	return OK;

}
/*****************************************************************************                  
* 函数名称: UpdateList
* 功能描述: 更新单链表
* 输入参数: LinkList L	              提供头指针
	     int position	          提供待更新结点的位置
* 输出参数: 更新单链表的某个结点
* 返 回 值: TREE : 两个数相等;FALSE :两数不等 
******************************************************************************/
int UpdateList(LinkList L, int position, void (*Input)(int *))
{
	int counter = 0;
	int value;

	if(position <1 || position > L->num)
	{
		return ILLEGAL;
	}
	
	Input(&value);

	L->pcur = L->phead;
	while(NULL != L->pcur)
	{
		counter++;
		if(counter == position)
		{
		    L->pcur->data = value;	
			return OK;
		}

		L->pcur = L->pcur->next;
	}
	return OK;
}
/*****************************************************************************                  
* 函数名称: SortList
* 功能描述: 对单链表直接插入排序
* 输入参数: LinkList L	       提供头指针
* 输出参数: 按数值的升序排序
* 返 回 值: OK : 排序成功
******************************************************************************/
int SortList(LinkList L)
{
	ListNode *first; //为原链表剩下用于直接插入排序的节点头指针
	ListNode  *t,*p,*q; //临时指针变量
	first = L->phead->next; //原链表剩下用于直接插入排序的节点链表
	L->phead->next = NULL; //只含有一个节点的链表的有序链表

	while (first != NULL) //遍历剩下无序的链表
	{
		for (t=first, q=L->phead; ((q!=NULL) && (q->data < t->data)); p=q, q=q->next); //无序节点在有序链表中找插入的位置
	
		/*退出for循环,就是找到了插入的位置*/
		first = first->next; //无序链表中的节点离开,以便它插入到有序链表中。 
		if (q == L->phead) //插在第一个节点之前
		{
  			 L->phead = t;    
		}
		else //p是q的前驱
		{
	   		p->next = t;   
		}
			t->next = q; //完成插入动作
		/*first = first->next;*/
	}
	return OK;
}
/*****************************************************************************                  
* 函数名称: Equal
* 功能描述: 判断两个数是否相等
* 输入参数: int *value1	              提供第一个数
	     int *value2	              提供第二个数
* 输出参数: 判断两个数是否相等
* 返 回 值: TREE : 两个数相等;FALSE :两数不等 
******************************************************************************/
int Equal(int *value1,int *value2)
{
	if(*value1 == *value2)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
/*****************************************************************************                  
* 函数名称:LengthofList 
* 功能描述:求链表长度
* 输入参数:LinkList L	              提供头指针
	    int *length          接受单链表的长度
* 输出参数:求链表L的长度
* 返 回 值: OK : 成功返回单链表的长度 
******************************************************************************/
int LengthofList(LinkList L,int *length)
{
	*length = L->num;
	return OK;
}
/*****************************************************************************                  
* 函数名称:ClearList 
* 功能描述:清空链表
* 输入参数:LinkList L	              提供头指针
* 输出参数:清空单链表
* 返 回 值: OK : 单链表清空成功 
******************************************************************************/
int ClearList(LinkList L)
{
	ListNode *ptTemp;
	L->pcur = L->phead;
	while( NULL != L->pcur)
	{
		ptTemp = L->pcur;
		L->pcur = L->pcur->next;
		free(ptTemp);
	}
	L->phead = NULL;
	return OK;	
}
/*****************************************************************************                  
* 函数名称:DisplayList 
* 功能描述:打印单链表
* 输入参数:LinkList L	              提供头指针
            void (*Visit)(int *) 提供结点值的输出函数
* 输出参数:打印单链表
* 返 回 值: OK : 打印成功 
******************************************************************************/
int DisplayList(LinkList L,void (*Visit)(int *))
{
	L->pcur = L->phead;
	if(NULL == L->pcur)
	{
		return ERROR;
	}
	while(NULL != L->pcur)
	{
		 Visit(&L->pcur->data);//将函数的指针作为参数
		 L->pcur = L->pcur->next;
	}
	return OK;
}

        


main.c

#include <stdio.h>
#include <stdlib.h>
#include "list.h"

void Menue(void);//对菜单函数声明

/*****************************************************************************
* 函数名称: OutputElem()
* 功能描述: 对链表数据进行输出
* 输入参数: int *pelnvalue 
* 输出参数: *pelnvalue
* 返 回 值: 无
******************************************************************************/
void OutputElem(int *pelnvalue)
{
	printf(" %d ",*pelnvalue);
}
/*****************************************************************************
* 函数名称: InputElem()
* 功能描述: 对链表数据进行输入
* 输入参数: int *pelnvalue
* 输出参数: *pelnvalue
* 返 回 值: 无
******************************************************************************/
void InputElem(int *pelnvalue)
{
	printf("请输入结点的值!");
	scanf("%d",pelnvalue);
}
/*****************************************************************************
* 函数名称: main
* 功能描述: 主函数
******************************************************************************/
int main()
{
    LinkList L = NULL;//定义一个链表,并为空
	int choice;  //用户编号选择
	int State;  //接受返回值


	while(1)
	{				
		Menue();		
		printf("\n请选择功能编号!");
		scanf("%d",&choice);	

		switch(choice)
		{
		case 0:
			{
				system("clear");
				exit(0);
			}
		case 1:
			{
				if(OVERFLOW ==InitList(&L))
				{
					printf("空间溢出,初始化单链表失败!");	
				}
				if(OK == InitList(&L))
				{
					system("clear");
					printf("初始化单链表成功!\n");
				}
				break;
			}
		case 2:
			{
				State = CreateListHead(L,InputElem);//头插法创建链表
				if(OVERFLOW == State)
				{				
					printf("\n单链表创建失败!\n");
				}
				if(OK == State)
				{	
					system("clear");
					printf("\n单链表创建成功!");
				}
				break;
			}
		case 3:
			{			
				State = CreateListTail(L,InputElem);//尾插法创建链表
				if(OVERFLOW == State)
				{					
					printf("\n单链表创建失败!\n");
				}
				if(OK == State)
				{
					system("clear");
					printf("\n单链表创建成功!");
				}
				break;			
			}
		case 4:
			{
				system("clear");
				State = DisplayList(L,OutputElem);//打印链表的值
				if(State == OK)
				{
					printf("\n");
				}
				if(State == ERROR)
				{
					printf("\n链表为空,没有元素!");
				}
				
				break;
			}
		case 5:
			{
				ListNode *p = NULL;
				int posit;//要查找的位置
				int temp;//查找到的结点的值

				system("clear");
				printf("\n输入你要查找的位置:");
				scanf("%d",&posit);
				if(OK == FindListOrder(L,posit,&temp))//按序号查找链表
				{
					printf("单链表第%d个位置的值为:%d\n",posit,temp);
				}
				else
				{
					printf("你查找的位置不合法!\n");
				}
				break;
			}			

		case 6:
			{
				int posit;//接受查找到的位置
				int temp;//所要查找结点的值
                system("clear");
                printf("\n请输入你要查找的数!");
				InputElem(&temp);
				if(OK == FindListValue(L,&temp,&posit,Equal))//按值查找链表的值
				{
					printf("单链表第%d个位置的值为:%d\n",posit,temp);
				}
				else
				{
					printf("该值不在链表中,没找到!\n");
				}
				break;
			}
		case 7:
			{
				int len;//接受单链表的长度
				system("clear");
				LengthofList(L,&len);//求链表的长度
				printf("\n单链表的长度为: %d",len);
				
				break;
			}
		case 8:
			{
				int posit;
				system("clear");
				printf("请输入你所要插入的位置!\n");
				scanf("%d",&posit);
				State = InsertList(L,posit,InputElem);
				if(State == OK)
				{
					printf("\n插入数据成功!");
				}
				if(State == ILLEGAL)
				{
					printf("\n插入的位置不合法!");
				}
				break;
			}
		case 9:
			{
				int posit;
				int outvalue;//带出删除结点的值
				system("clear");
				printf("请输入你所要删除的位置!\n");
				scanf("%d",&posit);
				State = DeleteList(L, posit, &outvalue);
				if(State == OK)
				{
					printf("删除成功!\n");
					printf("你删除的数据为:%d\n",outvalue);
				}	
				if(State == ILLEGAL)
				{
					printf("删除的位置不合法!\n");
				}
				break;
			}
		case 10:
			{
				int posit;
				printf("请输入你要更新的位置!");
				scanf("%d",&posit);

				State = UpdateList(L,posit, InputElem);
				if(ILLEGAL == State)
				{
					printf("输入的位置不合法!\n");
				}
				if(OK == State)
				{
					printf("更新数据成功!\n");
				}
				break;				
			}
		case 11:
			{
				if(OK == SortList(L))
				{
					system("clear");
					printf("链表已经从小到大排好序!\n");
					break;
				}
			}
		case 12:
			{			
				system("clear");
				if(OK == ClearList(L))
				{
					printf("链表已被清空!\n");
				}
				break;
			}
		default :
			printf("输入编号不合法!");
			break;
		}
	}  
	return 0;
}
/*****************************************************************************
* 函数名称: Menue()
* 功能描述: 菜单函数,显示操作菜单
* 输入参数: 无
* 输出参数: 无
* 返 回 值:  无
******************************************************************************/
void Menue(void)
{
	printf("\n ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁");
	printf("\n ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱" );
	printf("\n┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓");
	printf("\n┃              单链表子系统              ┃");
	printf("\n  ┃━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┃  ");
	printf("\n  ┃           0 退      出             ┃  ");
	printf("\n  ┃           1 初  始  化             ┃  ");
	printf("\n  ┃           2 头  插  法             ┃  ");
	printf("\n  ┃           3 尾  插  法             ┃  ");
	printf("\n  ┃           4 显      示             ┃  ");
	printf("\n  ┃           5 按位  查找             ┃  ");
	printf("\n  ┃           6 按值  查找             ┃  ");
	printf("\n  ┃           7 求链  表长             ┃  ");
	printf("\n  ┃           8 插入  结点             ┃  ");
	printf("\n  ┃           9 删除  结点             ┃  ");
	printf("\n  ┃          10 更新  结点             ┃  ");
	printf("\n  ┃          11 链表  排序             ┃  ");
	printf("\n  ┃          12 清空  链表             ┃  ");
	printf("\n┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
	printf("\n┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值