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

被折叠的 条评论
为什么被折叠?



