下面是对链表进行操作的前期准备工作—-创建一个链表
typedef int DataType;
typedef struct LinkList
{
struct LinkList* next;
DataType data;
}ListNode;
void InitLinkList(ListNode** pplist)//初始化
{
assert(pplist);
*pplist = NULL;
}
ListNode* BuyNode(DataType data)
{
ListNode* pNewNode = (ListNode*)malloc(sizeof(ListNode));
if (pNewNode == NULL)
{
perror("buy node::error");
return NULL;
}
pNewNode->data = data;
pNewNode->next = NULL;
return pNewNode;
}
void PushBack(ListNode** pplist, DataType d)//后插
{
assert(pplist != NULL);
if (*pplist == NULL)
{
ListNode* newnode = BuyNode(d);
if (newnode == NULL)
return;
*pplist = newnode;
}
else
{
ListNode* cur = *pplist;
while (cur->next != NULL)
{
cur = cur->next;
}
cur->next = BuyNode(d);
}
}
- 从尾到头打印单链表
思路:运用递归先找到最后一个节点,然后逆序打印
void PrintFromTailToFront(ListNode* pHead)//从尾到头打印单链表
{
//assert(pHead);
if (pHead)
{
PrintFromTailToFront(pHead->next);
printf("%d ", pHead->data);
}
}
- 删除一个无头单链表的非尾节点(不能遍历链表)
思路:不动第一个节点,将第二个节点的值赋给第一个节点,让第一个节点的next指向第二个节点的next ,删除第二个节点,
知道链表只剩下一个节点
void DelectListNotTail(ListNode* pHead)//删除一个无头单链表的非尾节点
{
ListNode* pDel = NULL;
while (pHead && pHead->next)
{
pDel = pHead->next;
pHead->data = pDel->data;
pHead->next = pDel->next;
free(pDel);
}
}
- 在无头单链表的一个节点前插入一个节点(不能遍历链表)
思路:先获取要插位置的节点信息,创建一个与要插位置节点data相同的节点,将新节点后插到指定的插入节点后面,然后将插入位置的节点值改为要插入节点的值,这样就完成了前插。
如图:要在3前面插入6
这是链表初试状态
创建节点,后插在3的后面
更改原始节点3的值为6
这样就完成了前插
代码:
ListNode* FindPosNode(ListNode* pHead, DataType pos)//找到指定节点的位置
{
assert(pHead);
while (pHead->data != pos)
{
pHead = pHead->next;
}
return pHead;
}
void InsertPosFront(ListNode* pos, DataType data)//在无头单链表的一个节点前插入一个节点(不能遍历链表)
{
ListNode* NewNode = NULL;
NewNode = BuyNode(pos->data);
NewNode->next = pos->next;
pos->next = NewNode;
pos->data = data;
}
- 单链表实现约瑟夫环
思路:先创建一个环形链表,每次开始计数,当数到第m个节点时,将这个节点删除,删除的方法是将m的下一个节点的数据赋值给第m个节点,删除m的下一个节点(和上面的方法相似)
ListNode* LastNode(ListNode* pHead)//找最后一个节点
{
//ListNode* Last;
assert(pHead);
while (pHead->next)
{
pHead = pHead->next;
}
return pHead;
}
ListNode* Last = LastNode(pHead);//找最后一个节点
Last->next = pHead;//单链表成环
ListNode* TosephCircle(ListNode* pHead,int m)//约瑟夫环
{
int count = 0;
ListNode* Del = NULL;
while (pHead->next != pHead)
{
count = m;
while (--count)
{
pHead = pHead->next;
}
Del = pHead->next;
pHead->data = Del->data;
pHead->next = Del->next;
free(Del);
}
pHead->next = NULL;
return pHead;
}
- 逆置/反转单链表
思路:遍历链表,将链表节点通过头插的方式创建一个新的链表,最后将旧链表的头指针指向新链表(要传二级指针,这里要改变链表头指针的指向)
void ReverseList(ListNode** pHead)//逆置单链表
{
ListNode* pNext = NULL;
ListNode* pCur = NULL;
ListNode* pNew = NULL;
pCur = *pHead;
while (pCur)
{
pNext = pCur->next;
pCur->next = pNew;
pNew = pCur;
pCur = pNext;
}
*pHead = pNew;
}