单向链表的一些操作

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

//声明枚举类型,linux下C语言没有bool类型
typedef enum bool{
	false = 0,
	true = 1
}bool;

typedef struct Node
{
	int data;//数据域
	struct Node* pNext;	//指针域
}NODE, *PNODE;					//NODE等价于 struct Node, PNODE等价于struct Node*


	
//函数声明部分
PNODE createList();				//分配内存创建list
void traverseList(PNODE pHead);			//遍历list
bool isEmpty(PNODE pHead);			//判断是否为空
bool insertList(PNODE, int, int);		//插入数据,postion从1开始
bool deleteList(PNODE, int, int*);		//删除数据
int lengthList(PNODE pHead);			//返回长度
void sortList(PNODE pHead);			//排序


int main()
{
	PNODE pHead = NULL;		//struct Node *pHead = NULL;
	int count = 0;			//链表长度
	int delvalue;			//要删除数据
	
	pHead = createList();		//创建一个非循环单链表,并将该链表的头结点地址赋给pHead
	traverseList(pHead);		//遍历list
	if(isEmpty(pHead))
		printf("链表为空!\n");
	else
		printf("链表不为空\n");
		
		sortList(pHead);
		traverseList(pHead);
		
		insertList(pHead,2,100);
		
		traverseList(pHead);
		count = lengthList(pHead);
		
		printf("链表长度是:%d\n",count);
		if(deleteList(pHead,2,&delvalue))
			
			printf("删除成功,删除的元素是:%d\n",delvalue);
		else
			printf("删除失败!\n");
		traverseList(pHead);
		count = lengthList(pHead);
		printf("链表长度是:%d\n",count);
		
	return 0;
}

bool deleteList(PNODE pHead, int postion, int* delValue)	//删除数据
{
	int i = 0;
	PNODE p = pHead;
	
	//使 p指向 postion 前面的一个结点 
	while(p->pNext != NULL && i< postion - 1)
	{
		p = p->pNext;
		++i;
	}	
	if(i > postion - 1 || p->pNext == NULL)
		return false;
		
		//删除操作
	PNODE q = p->pNext;
	*delValue = q->data;
	
	//删除p结点后面的结点
	p->pNext = p->pNext->pNext;
	free(q);
	return true;
}


//在pHead所指向链表的第postion个结点的前面插入一个新的结点,该结点的值是value
//并且postion从1开始
bool insertList(PNODE pHead, int postion, int value )		//插入数据
{
	int i = 0;
	PNODE p = pHead;
	
	//使 p指向 postion 前面的一个结点 
	while(p != NULL && i< postion - 1)
	{
		p = p->pNext;
		++i;
	}	
	if(i > postion - 1 || p == NULL)
		return false;
	
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	if(pNew == NULL)
		{
			printf("动态分配内存失败!\n");
			exit(-1);
		}
	pNew->data = value;
	
	PNODE q = p->pNext;
	p->pNext = pNew;
	pNew->pNext = q;
	
	return true;
}

void sortList(PNODE pHead)				//排序
{
	int temp,j,i;
	int length = lengthList(pHead);
	
	PNODE p,q;
	for(i = 0,p = pHead->pNext; i< length - 1;++i,p = p->pNext)
	{
		for(j = i+1,q = p->pNext; j< length; ++j,q = q->pNext)
		{
			if(p->data > q->data)
				{
					temp = p->data;
					p->data = q->data;
					q->data = temp;
				}
		}
	}
}

int lengthList(PNODE pHead)		//返回长度
{
	PNODE p = pHead->pNext;
	int count = 0;			//计数
	
	while(p != NULL)
	{
		++count;
		p = p->pNext;
	}
	return count;
}

bool isEmpty(PNODE pHead)		//判断是否为空
{		//头结点的指针域为空则链表为空
	if(pHead->pNext == NULL)
		return true;
	else
		return false;
}

PNODE createList()   			//create list and storage alloction 
{
	int length;   			//存放有效结点的个数
	int i;
	int value;			//临时存放用户输入的结点的值
	
	//分配了一个不存放有效数据的头结点
	PNODE pHead = (PNODE)malloc(sizeof(NODE));
	
	if(pHead == NULL)
		{
			printf("分配失败,程序终止!\n");
			exit(-1);
		}
		
		//假定pTail永远指向尾节点
		PNODE pTail = pHead;
		pTail->pNext = NULL;
		
		printf("请输入要生成结点的个数:length = ");
		scanf("%d",&length);
		
		for(i = 0; i< length; ++i)
		{
			printf("请输入 %d 个结点的值:",i+1);
			scanf("%d",&value);
			
			PNODE pNew = (PNODE)malloc(sizeof(NODE));
			if(pNew == NULL)
				{
					printf("分配失败,程序终止!\n");
					exit(-1);
				}
				
				pNew->data = value;
				pTail->pNext = pNew;
				pNew->pNext = NULL;
				pTail = pNew;
		}
		return pHead;
}

void traverseList(PNODE pHead)  //traverse list ,遍历链表不能用下标,因为链表不是数组
{
	PNODE p = pHead->pNext;
	
	//当指针p指向的不为空一直输出
	while(p != NULL)
	{
		printf("%d ",p->data);
		p = p->pNext;
	}
	printf("\n");
}


//createList();函数给链表动态分配内存

//1.example: 
//int i = 10;
//int *p = (int *)malloc(100);
//解释:int i = 10;是临时分配的局部变量,函数调用完内存就会释放
//而用malloc申请的内存在函数调用完后,指针p会释放但是申请的100字节的内存不会释放。

//2.method:
//可以再一个函数中分配内存然后在别的主调函数中使用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值