您的位置:首页 > 其它

单链表(增、删、查找)

2016-06-01 17:40 375 查看
     用结构体构建单链表,实现单链表的基本功能。

//头文件
#pragma once
#include<stdio.h>
#include<assert.h>
#include<malloc.h>

typedef int DataType;
typedef struct ListNode
{
DataType _data;
struct ListNode *_next;
}ListNode;

//初始化
void InitList(ListNode **ppHead)
{
*ppHead = NULL;
}

//销毁节点
void DestoryList(ListNode*& pHead)
{
ListNode* cur = pHead;
while (cur)
{
ListNode* tmp = cur;
cur = cur->_next;
free(tmp);
}
pHead = NULL;
}

ListNode* BuyNode(DataType x)
{
ListNode* tmp = (ListNode*)malloc(sizeof(ListNode));
assert(tmp);

tmp->_data = x;
tmp->_next = NULL;
return tmp;
}

//尾插  
void PushBack(ListNode** ppHead, DataType x)   
{
assert(ppHead);

if (*ppHead = NULL)
{
*ppHead = BuyNode(x);
}
else
{
ListNode *tail = *ppHead;
while (tail->_next != NULL)
{
tail = tail->_next;
}
tail->_next = BuyNode(x);
}
}

//头插
void PushFront(ListNode* &pHead, DataType x)
{
if (pHead == NULL)
{
pHead = BuyNode(x);
}
else
{
ListNode * tmp = BuyNode(x);
tmp->_next = pHead;
pHead = tmp;
}
}

void PrintList(ListNode *pHead)
{
ListNode *cur = pHead;
while (cur != NULL)
{
printf("%d->", cur->_data);
cur = cur->_next;
}
printf("NULL\n");
}

//尾删
void PopBack(ListNode* &pHead)
{
if (pHead == NULL)
{
printf("List is empty\n");
return;
}
else if (pHead->_next == NULL)
{
free(pHead);
pHead = NULL;
}
else
{
ListNode* prevTail = NULL, *tail = pHead;
while (tail->_next != NULL)
{
prevTail = tail;
tail = tail->_next;
}
prevTail->_next = NULL;
free(tail);
}
}

//头删
void PopFront(ListNode*& pHead)
{
if (pHead == NULL)
{
printf("List is empty.\n");
return;
}
else
{
ListNode* tmp = pHead;
pHead = tmp->_next;
free(tmp);
}
}

ListNode *Find(ListNode *pHead, DataType x)
{
ListNode *cur = pHead;
while (cur)
{
if (cur->_data == x)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}

void Insert(ListNode* pos, DataType x)
{
assert(pos);

ListNode *tmp = BuyNode(x);
tmp->_next = pos->_next;
pos->_next = tmp;

/*ListNode *next = pos->_next;
ListNode *tmp = BuyNode(x);  //插入的节点
pos->_next = tmp;
tmp->_next = next;
*/
}

void Erase(ListNode* &pHead, ListNode *pos)
{
assert(pos);

if (pos == pHead)
{
pHead = pHead->_next;
free(pHead);
}
else
{
ListNode* cur = pHead;
while (cur)
{
if (cur->_next != pos)
{
cur->_next = pos->_next;
free(pos);
break;
}
cur = cur->_next;
}
}
}

void DelNonTailNode(ListNode* pos)//删除不知头和不是尾部的节点
{
assert(pos&&pos->_next);

pos->_data = pos->_next->_data;
ListNode *next = pos->_next->_next;
free(pos);
pos->_next = next;
}

void Remove(ListNode* &pHead, DataType x)
{
ListNode* ret = Find(pHead, x);
if (ret)
{
Erase(pHead, ret);
}
/*
ListNode *node1 = pHead;
ListNode *node2 = NULL;
if (pHead == NULL)
{
return ;
}
else
{
if (node1->_data == x)
{
pHead = pHead->_next;
free(node1);
return ;
}
else
{
while (node1 != NULL)
{
node2 = node1;
node2 = node2->_next;
if (node2->_data== x)
{
node1->_next = node2->_next;
free(node2);
break;
}
node1 = node1->_next;
}
}
}*/
}

void Reverse(ListNode* &pHead)      //逆置
{
if (pHead == NULL || pHead->_next == NULL)
{
return;
}
ListNode* cur = pHead;
ListNode* newHead = NULL;
while (cur)
{
ListNode* tmp = cur;
cur = cur->_next;
tmp->_next = newHead;
newHead = tmp;
}
pHead = newHead;
}

void PrintTailToHead(ListNode *pHead)
{
if (pHead)
{
PrintTailToHead(pHead->_next);

printf("%d\n",pHead->_data);
}
}

ListNode* FindMid(ListNode* pHead)//查找单链表的中间节点,要求只能遍历一次链表(快慢指针,一个走一步,另一个走两步)
{
if (pHead == NULL || pHead->_next == NULL)
{
return pHead;
}

ListNode* fast = pHead;
ListNode* slow = pHead;
while (fast)
{
fast = fast->_next->_next;
slow = slow->_next;
}
return slow;
}

void InsertFrontNode(ListNode* pos,DataType x)
{
assert(pos);

ListNode* tmp = BuyNode(x);
tmp->_next = pos->_next;
pos->_next = tmp;

DataType tmpData = tmp->_data;
tmp->_data = pos->_data;
pos->_data = tmpData;

}

ListNode* JosephCycle(ListNode* pHead, int m)//删除节点
{
ListNode* cur = pHead;
if (cur == NULL)
return NULL;

while (1)
{
//只剩一个节点
if (cur = cur->_next)
{
return cur;
}

int x = m;
while (--x)//走m-1步
{
cur = cur->_next;
}
//替换法进行删除
cur->_data = cur->_next->_data;
ListNode* del = cur->_next;
cur->_next = del->_next;

free(del);
}
}

//快速排序
//冒泡排序
void SortList(ListNode* pHead)
{

if (pHead == NULL || pHead->_next == NULL)
return;
ListNode *tail = NULL;
ListNode*cur = pHead->_next;
ListNode*prev = pHead;

while (tail != pHead)
{
int exchange = 0;//优化不交换情况
while (cur != tail)
{

if (cur->_data <prev->_data)
{
DataType temp = cur->_data;
cur->_data = prev->_data;
prev->_data = temp;
exchange = 1;
}
prev = cur;
cur = cur->_next;
}
if (exchange == 0)
return;
tail = prev;

prev = pHead;
cur = pHead->_next;
}
}

//合并两个有序链表,合并后仍有序   先摘  后尾插
ListNode* MergeList(ListNode *pHead1, ListNode* pHead2)
{
if (pHead1 == NULL)
{
return pHead2;
}
if (pHead2 == NULL)
{
return pHead1;
}

ListNode*cur1 = pHead1;
}

ListNode* FindKTailNode(ListNode* pHead, int k)
{
ListNode *fast = pHead, *slow = pHead;
while (--k)
{
if (fast == NULL)
{
return NULL;
}
fast = fast->_next;

if (fast == NULL)
{
return NULL;
}
}

while (fast->_next)
{
slow = slow->_next;
fast = fast->_next;
}
return slow;
}

//合并两个有序链表
ListNode* MergeList(ListNode*pHead1, ListNode*pHead2)
{
if (pHead1 == NULL)
return pHead2;
if (pHead2 == NULL)
return pHead1;
ListNode*newHead;
ListNode*cur1 = pHead1;
ListNode*cur2 = pHead2;
ListNode*tail = NULL;
if (cur1->_data < cur2->_data)
{
newHead = cur1;
cur1 = cur1->_next;
}
else
{
newHead = cur2;
cur2 = cur2->_next;
}
tail = newHead;//
while (cur1&&cur2)
{
if (cur1->_data< cur2->_data)
{
tail->_next = cur1;
cur1 = cur1->_next;
}
else
{
tail->_next = cur2;
cur2 = cur2->_next;
}
tail = tail->_next;

if (cur1 == NULL)
tail->_next = cur2;
if (cur2 == NULL)
tail->_next = cur1;
}
return newHead;
}

//判断链表是否带环,环长度,环入口点
void RingList(ListNode* pHead)
{

ListNode*slow = pHead;
ListNode*fast = pHead;

while (fast->_next)
{

slow = slow->_next;
fast = fast->_next;
if (fast->_next)
fast = fast->_next;
if (slow == fast)
{
printf( "链表中存在环\n" );
//ListNode *tmp = slow;
slow = slow->_next;
int k = 1;
while (slow != fast)
{
slow = slow->_next;
k++;
}
printf("链表环长度为 %d\n", k );
//一步走必然会在环上次相遇的地方再次相遇
//当slow进入环时,必然会与fast相遇,最初想遇的就是环入口点
slow = pHead;
while (slow != fast)
{
slow = slow->_next;
fast = fast->_next;
}

printf( "环入口值为:%d\n" , slow->_data );
return;
}

}
printf("链表中不带环\n");
}

//链表相交
void Intersect(ListNode*pHead1, ListNode * pHead2)
{
if (pHead1 == NULL || pHead2 == NULL)
{
printf( "List is not insersect\n" );
return;
}

ListNode *cur1 = pHead1;
ListNode *cur2;
while (cur1)
{
cur2 = pHe
9e4e
ad2;
cur1 = cur1->_next;
while (cur2)
{
if (cur1 == cur2)
{
printf( "链表相交,交点值为:%d\n", cur1->_data );
return;
}
cur2 = cur2->_next;
}

}
printf( "链表不相交\n");
return;
}

int Size(ListNode*pHead)
{
assert(pHead);

int size = 0;
ListNode*cur = pHead->_next;

while (cur)
{
++size;
cur = cur->_next;
}
return size;
}


//测试

#include<stdio.h>
#include"ListNode.h"

void test1()
{
ListNode * list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PrintList(list);

PopFront(list);
PopFront(list);
PopFront(list);
PrintList(list);

ListNode* ret = Find(list, 3);
Erase(list, ret);
PrintList(list);

ListNode *ret1 = Find(list, 3);
InsertFrontNode(list, ret1->_data);
}

int main()
{
test1();
return 0;
}

本文出自 “二负” 博客,请务必保留此出处http://10324470.blog.51cto.com/10314470/1770126
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: