数据结构与算法C语言版---链表

  

由于编者水平有限,如有错误,请多多包涵。


/*
	File name: LinkendList.cpp
	Description: 有头链表的创建,遍历,查找,删除,添加,排序。
	Author: Yang_Jiang
	Date: 2018年10月10日
	Compiler:Visual Studio 2008
*/

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

typedef struct Student
{
	int id; // 数据域
	struct Student* pNext;  //指针域
}NODE,*PNODE; 

//NODE 等价于 struct Student
//PNODE 等价于 struct Student*


//函数声明
PNODE create_list(int ); //创建链表  PNODE返回该链表头结点
void traverse_list(PNODE ); // 遍历该链表
bool find_list(PNODE , int); //查找该链表中数据 true:找到数据 false:链表为空或未找到数据
int length_list(PNODE ); //判断该链表长度
bool delete_list(PNODE , int); //删除该链表中的数据 true:删除成功 false:链表为空或删除失败
bool empty_list(PNODE ); //判断链表是否为空   true:空 false:非空
void insert_list(PNODE , int val ); //插入节点 根据id大小 如果链表为空默认插在头结点后面,否则按从小到大顺序插入
void sort_list(PNODE);//对链表进行排序 --- 冒泡排序法

int main()
{

	PNODE pHead = create_list(30); //创建链表 长度为0(只有头结点)
	sort_list(pHead);
	traverse_list(pHead);

	//find_list(pHead,31); //查找 true 数据存在 false 链表为空或数据不存在
	
	//delete_list(pHead,1); //删除 true 删除成功 false 链表为空或数据不存在
	
	//insert_list(pHead,0); //没有数据的时候默认插入在头结点后面
	//insert_list(pHead,0);
	//insert_list(pHead,2);
	//insert_list(pHead,1);
	
	//traverse_list(pHead);  //遍历

	return 0;
}


//创建链表
PNODE create_list(int len)
{
	PNODE pHead = (PNODE) malloc(sizeof(NODE));
	if(NULL == pHead)
	{
		exit(-1); //动态内存分配失败,程序终止!
	}
	
	PNODE head = pHead;
	head->pNext = NULL;

	for(int i=0; i<len; i++)
	{
		PNODE pNew = (PNODE) malloc(sizeof(NODE));
		if(NULL == pNew)
		{
			exit(-1); //动态内存分配失败,程序终止!
		}
		
		pNew->id = i + 1;
		head->pNext = pNew;
		pNew->pNext = NULL;
		
		head = pNew; //直接指向最后一个节点 ,每一次循环直接挂到最后一个节点后边。

		/*
			挂载到节点后面:
			
			如果实在理解不了head = pNew; 那么直接做一个循环,每次遍历到最后个节点挂载上去
			数据量多的话,效率会下降。

			while( head->pNext != NULL )
			{
				head = head->pNext; //遍历到最后一个节点
			}
			pNew->id = i + 1;
			head->pNext = pNew; //挂载到最后一个节点后面
		    
			result : 1,2,3,4,5,6,7.....29,30
		*/
		
		/*
			挂载到节点前面:
			
			pNew->id = i + 1;
			pNew->next = head->next; // 把头节点的第一个有效的数据 挂载到新来的节点后边
			head->next = pNew; //把挂载好的数据 挂在头节点的后边
			
			result : 30,29,28,27,26,25......2,1
		*/


	}

	return pHead;
}

//判断链表是否为空
bool empty_list(PNODE pHead)
{
	if(pHead->pNext == NULL)
	{
		return true; //为空
	}
	
	return false; //不为空
}

//求链表长度
int length_list(PNODE pHead)
{
	if( empty_list(pHead) ) //链表为空
	{
		return 0; 
	}
	else
	{	
		int count = 0; //计数
		PNODE head = pHead->pNext;
		
		while( head != NULL)
		{
			count ++;
			head = head->pNext;
		}
		return count;
	}
}


//遍历链表
void traverse_list(PNODE pHead)
{
	PNODE head = pHead->pNext; //头结点不包含有效数据,首节点才包含有效数据
	
	if( empty_list(pHead) ) //判断链表是否为空
	{
		printf("空链表\n");
	}
	else
	{
		while( head != NULL ) //只要不为空
		{
			printf("%d\t", head->id);
			head = head->pNext; //指向下一个元素
		}

	}
}

//查找数据
bool find_list(PNODE pHead, int val)
{
	if( empty_list(pHead) ) //链表为空 
	{
		return false;
	}
	else
	{
		PNODE head = pHead->pNext;

		while( head != NULL )
		{
			if(head->id == val )
			{
				printf("该数据存在%d\n" , val);
				return true;
			}
			head = head->pNext;
		}

		return false; //如果遍历完了还没找到该数据

	}
	
}

//删除数据
bool delete_list(PNODE pHead, int val)
{
	if( empty_list(pHead) )
	{
		return false; //链表为空 无法删除
	}
	else
	{
		PNODE pre = pHead; // 前一个节点
		PNODE cur = pHead->pNext; //当前节点
		
		while( cur != NULL)
		{
			if(cur->id == val)
			{
				pre->pNext = cur->pNext; //等价于 pre->pNext = pre->pNext->pNext		
				printf("删除成功,您删除的数据是%d\n" ,cur->id);
				free(cur); //必须得释放,否则会造成内存泄漏。
				cur = NULL;
				
				return true; //删除成功
			}
			pre = cur; 
			cur = cur->pNext;
		}
	
		return false; //没找到数据 删除失败
	}
}

void insert_list(PNODE pHead, int val)
{
	
	PNODE pre = pHead;     //前一个节点
	PNODE cur = pHead->pNext; //当前节点

	if( empty_list(pHead) ) //如果链表为空
	{
		printf("该链表为空,数据直接插入在首节点\n");
		
		PNODE pNew = (PNODE) malloc(sizeof(NODE));
		if(NULL == pNew)
		{
			exit(-1);
		}
		pNew->id = val;
		pNew->pNext = NULL;
		
		pHead->pNext = pNew; //如果链表为空直接挂在有效节点后面 cur 等价于 pHead->next;
	}
	else
	{
		while( cur != NULL)
		{
			if(cur->id > val) //如果当前的值小于 用户传进来的值 
			{
				break;  //表示找到要插入的位置 直接终止循环
			}
			pre = cur;
			cur = cur->pNext;
		}
		
		PNODE pNew = (PNODE) malloc(sizeof(NODE));
		if(NULL == pNew)
		{
			exit(-1); //动态内存分配失败,程序终止!
		}
		pNew->id = val;
		pNew->pNext = NULL;
		
		
		pNew->pNext = cur;// cur 等价于 pHead->next(当前节点); 
		pre->pNext = pNew;// pre 等价于 pHead(上一个节点);
		printf("插入成功!\n");
	}
	
}

void sort_list(PNODE pHead)
{
	int len = length_list(pHead); //求出链表长度
	
	int i,j,t;
	
	PNODE p;
	PNODE q;

	for(i=0,p=pHead->pNext; i<len-1; i++,p=p->pNext )
	{	
		//或 for(j=0,q=p->pNext; j<len-1-i; j++,q=q->pNext)
		for(j=i+1,q=p->pNext; j<len; j++, q=q->pNext)
		{
			if(p->id < q->id) // 类似于 i > j
			{
				t = p->id; // 类似于 t = i;
				p->id = q->id; //类似于 i = j;
				q->id = t; //类似于 j = t;
			}
		
		}
		
	}

}



/*
	总结
		注释已经写的足够详细。
		本程序在Visual Studio 2008编译通过,文件是.cpp文件,代码的写法有点不规范,既有C语言
		语法也包含了C++语法
*/

相关文章