单向链表简单操作代码实现

包含尾插法构造确定个数和元素的单向链表,链表遍历输出,获得某位置节点前驱元素任意两个节点操作。链表插入、删除操作(包含删除一个节点和全部删除),冒泡法交换节点值进行链表排序,以及测试用例。

#include<stdio.h>
#include<stdlib.h>
/*注意链表头结点为NULL的输入检查*/
typedef struct ListNode
{
	int val;
	ListNode *next;
};
/*尾插法构建单向链表*/
ListNode* tailCreatList(int listLen)
{
	int val;
	ListNode *pHead, *pTail,*pNode;
	pHead = (ListNode*)malloc(sizeof(ListNode));
	if (pHead == NULL)
	{
		printf("Memory allocte failed!\n");
		exit(-1);
	}	
	pHead->next = NULL;
	pTail = pHead;
	while (listLen--)
	{
		pNode = (ListNode*)malloc(sizeof(ListNode));
		if (pNode == NULL)
		{
			printf("Memory allocte failed!\n");
			exit(-1);
		}
		scanf_s("%d", &val);
		pNode->val = val;
		pTail->next = pNode;
		pNode->next = NULL;
		pTail = pNode;
	}
	return pHead;
}
/*判断链表是否为空*/
int isEmpty(ListNode* pHead)
{
	return pHead->next == NULL;
}
/*打印输入节点之后各节点值*/
void printList(ListNode* pHead)
{
	if (pHead == NULL)
	{
		printf("invalid input arg!!\n");
		system("pause");
	}
	if (isEmpty(pHead))
	{
		printf("List is empty!!\n");//可能是到达尾节点造成的打印空
		return;
	}
	ListNode *pCurrNode;
	pCurrNode = pHead->next;
	while (pCurrNode)
	{
		printf("%d", pCurrNode->val);
		if (!(pCurrNode->next == NULL))
			printf(" - > ");
		else
			printf("\n");
		pCurrNode = pCurrNode->next;
	}
		
}
/*对于链表的各种操作,首先明确通过何种先验信息去查找前驱节点*/
/*通过节点数据获得该节点前驱节点*/
ListNode * findPreNodeByValue(ListNode* pHead,int val)
{
	if (pHead == NULL)
	{
		printf("invalid input arg!!\n");
	}	
	if (isEmpty(pHead))
	{
		printf("List is empty!!\n");
		return NULL;
	}
	ListNode *pCurrNode;
	pCurrNode = pHead;
	while (pCurrNode->next != NULL && pCurrNode->next->val != val)
		pCurrNode = pCurrNode->next;
	if (pCurrNode->next == NULL)
	{
		printf("No found such element!!\n");
		//exit(-1);
		system("pause");
		return NULL;
	}
		
	return pCurrNode;//如果val没有找到则会返回NULL
}
/*通过节点顺序获得该节点前驱节点*/
ListNode * findPreNodeByOrder(ListNode* pHead, int order)
{
	if (isEmpty(pHead))
	{
		printf("List is empty!!\n");
		return NULL;
	}
	ListNode *pCurrNode;
	pCurrNode = pHead;
	--order;
	while (order--&&pCurrNode->next != NULL)
	{
		pCurrNode = pCurrNode->next;
		if (pCurrNode->next == NULL)
		{
			printf("no found for this postion!!\n");
			//exit(-1);
			system("pause");
			return NULL;
		}
		
	}
	return pCurrNode;
	
}
/*通过节点位置交换两个节点*/
void swapTwoNode(ListNode* pHead,int posOne, int posTwo)
{
	//如果输入的不是位置,而是指针,那么需要判断某一个指针是不是头指针,若是则不交换!
	//未检查该元素是否存在,可能不存在,但是可以找到前驱指针,是一个隐患,可以加一个判断是否该函数返回指针后继为空!!
	if (pHead == NULL || posOne == posTwo)
		return;
	if (posOne == 0 || posTwo == 0)
	{
		printf("invalid input argument!!");
		system("pause");
	}
		
	ListNode *pPosOnePreNode, *pPosTwoPreNode, *pTempNode,*pOneNode, *pTwoNode;
	pPosOnePreNode = findPreNodeByOrder(pHead, posOne);
	pPosTwoPreNode = findPreNodeByOrder(pHead, posTwo);
	if (pPosOnePreNode->next == NULL || pPosTwoPreNode->next == NULL)
	{
		printf("pos is beyond the range of linklist");
		system("pause");
	}
	if (posOne + 1 == posTwo)
	{
		pOneNode = pPosOnePreNode->next;
		pTwoNode = pOneNode->next;
		pPosOnePreNode->next= pTwoNode;
		pOneNode->next = pTwoNode->next;
		pTwoNode->next = pOneNode;
	}
	if (posTwo + 1 == posOne)
	{
		pTwoNode = pPosTwoPreNode->next;
		pOneNode = pTwoNode->next;
		pPosTwoPreNode->next = pOneNode;
		pTwoNode->next = pOneNode->next;
		pOneNode->next = pTwoNode;
	}
	else
	{
		//交换两节点后继指针,即后继元素地址
		pTempNode = pPosTwoPreNode->next->next;
		pPosTwoPreNode->next->next = pPosOnePreNode->next->next;
		pPosOnePreNode->next->next = pTempNode;
		//交换两节点前驱指针,即该节点自身地址
		pTempNode = pPosTwoPreNode->next;
		pPosTwoPreNode->next = pPosOnePreNode->next;
		pPosOnePreNode->next = pTempNode;
	}
	
}
/*在某位置节点前插入该节点*/
void insertNode(ListNode* pHead, int pos, int val)
{
	ListNode* pPreNode,*insertNode;
	insertNode = (ListNode*)malloc(sizeof(ListNode));
	if (pHead == NULL)
	{
		printf("Memory allocte failed!\n");
		exit(-1);
	}
	insertNode->val = val;
	pPreNode = findPreNodeByOrder(pHead, pos);
	//if (pPreNode == NULL)

	insertNode->next = pPreNode->next;
	pPreNode->next = insertNode;
}
/*删除某节点*/
void deleteNode(ListNode* pHead, int pos)
{
	ListNode *pPreNode,*pTempNode;
	pPreNode=findPreNodeByOrder(pHead, pos);
	pTempNode = pPreNode->next;
	pPreNode->next = pTempNode->next;
	free(pTempNode);
	pTempNode = NULL;
}
/*删除链表,注意头结点被保留!!*/
void deleteList(ListNode* pHead)
{
	ListNode *pCurrNode,*pTempNode;
	pCurrNode = pHead->next;
	pHead->next = NULL;
	while (pCurrNode)
	{
		pTempNode = pCurrNode->next;
		free(pCurrNode);
		pCurrNode = pTempNode;
	}
}
/*交换节点实现冒泡排序*/
/*void listBubbleSort(ListNode* pHead,int listLen)
{
	int i,j;
	ListNode* pTempNode,*pPreNode, *pFirstNode, *pSecondNode;
	if (!pHead->next->next)
		return;
	for (i = 0; i < listLen; i++)
	{
		pPreNode = pHead;
		
		for (j = 0; j < listLen - i - 1; j++)
		{
			pFirstNode = pPreNode->next;
			pSecondNode = pFirstNode->next;
			if (pFirstNode->val > pSecondNode->val)
			{
				pPreNode->next = pSecondNode;
				pFirstNode->next = pSecondNode->next;
				pSecondNode->next = pFirstNode;
			}
			pPreNode = pPreNode->next;
		}
	}
		
}*/
/*交换节点值实现冒泡排序*/
void listBubbleSort(ListNode* pHead, int listLen)
{
	//性能较低,可优化性很强!
	int i, tempVal;
	ListNode *pCurrNode;
	for (i = 0; i < listLen; i++)
	{
		pCurrNode = pHead->next;
		while (pCurrNode->next != NULL)
		{
			if (pCurrNode->val > pCurrNode->next->val)
			{
				tempVal = pCurrNode->next->val;
				pCurrNode->next->val = pCurrNode->val;
				pCurrNode->val = tempVal;
			}
			pCurrNode = pCurrNode->next;
		}
	}
}

int main()
{
	int listLen=0;
	ListNode *pHead = NULL,*pNewHead = NULL;
	while (scanf_s("%d", &listLen))
	{
		pHead = tailCreatList(listLen);
		//pNewHead = findPreNodeByValue(pHead, 5);
		//swapTwoNode(pHead, 4, 2);
		//insertNode(pHead, 4, 5);
		//deleteNode(pHead,3);
		//deleteList(pHead);
		listBubbleSort(pHead, listLen);
		printList(pHead);
		//printf("%d", listLen);
	}
		
	system("pause");
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值