单链表是数据结构中重要并且基础的一环,学习数据结构就需要知道单链表有的常用操作。
1> 单链表的头插式创建
2> 单链表的尾插式创建
3>单链表的长度计算
4>单链表的打印输出
5> 单链表的释放操作
6>单链表是否为空判断
7>单链表在指定index插入指定元素
8>单链表删除指定index的节点
9>单链表的逆置
10>两个有序单链表的合并成一个链表 不申请额外空间
11>单链表是否有环判断
/*
linklist.h
*/
#include <iostream>
typedef int DataType;
typedef struct Node
{
DataType data;
Node* next;
};
typedef Node* LinkList;
LinkList HeadCreateLinkList() // 头插式创建带头链表
{
Node* head = (Node*) malloc( sizeof(Node));
if (NULL == head)
{
std::cout << "tail create linklist head node and malloc buffer failed ~" << std::endl;
return NULL;
}
int tmp;
head->next = NULL;
std::cout << "Input list elems and -1 end !" << std::endl;
while( std::cin >> tmp )
{
if (-1 == tmp) break ;
Node* node = (Node*) malloc( sizeof(Node));
if (NULL == node){
std::cout << "tail create linklist elem node and malloc buffer failed ~" << std::endl;
exit(0);
}
node->data = tmp;
node->next = head->next;
head->next = node;
}
return head;
}
LinkList TailCreateLinkList() // 尾插式创建带头链表
{
Node* head;
Node* curNode;
head = (Node*)malloc( sizeof(Node));
if (head == NULL)
{
std::cout << "create linklist and malloc buffer failed ~" << std::endl;
return NULL;
}
curNode = head;
int tmp;
std::cout << "Input list elems and -1 over!" << std::endl;
while(std::cin >> tmp)
{
if (-1 == tmp) break ;
Node* sptr = (Node*)malloc( sizeof(Node));
if (sptr == NULL)
{
std::cout << "create linklist elems and malloc buffer failed ~" << std::endl;
exit(0);
}
sptr->data = tmp;
curNode->next = sptr;
curNode =sptr;
}
curNode->next = NULL;
return head;
}
int LinkListLength(LinkList list) // 计算链表长度 不包括头结点
{
int len = -1;
while(NULL != list)
{
len++;
list = list->next;
}
return len;
}
void PrintLinkList(LinkList list) // 带头节点链表打印
{
if (NULL == list) return;
Node *ptr = list->next;
std::cout << "list elems [" ;
while (NULL != ptr)
{
std::cout << " " << ptr->data;
ptr = ptr->next;
}
std::cout << " ]" << std::endl;
}
void DestoryLinkList(LinkList list) // 释放带头链表
{
Node* ptr = list;
Node* tmp;
while(ptr)
{
tmp = ptr->next;
free(ptr);
ptr = tmp;
}
std::cout << "LinkList is destory ~" << std::endl;
}
int Empty(LinkList list) // 判断链表是否为空
{
return ((list == NULL) || (list->next == NULL));
}
int InsertNode(LinkList list, int elem , int index) // 在index节点之前插入节点值为elem的节点 按照index
{
int len = LinkListLength(list);
if (index < 1 || index > len)
{
std::cout << "The index out range !" << std::endl;
return 0;
}
Node* cur = list;
for ( int i = 1; i < index; i++) // 找到第index节点的前驱节点
{
cur = cur->next;
}
Node* node = (Node*) malloc( sizeof(Node));
if (!node)
{
std::cout << "malloc memory failed for insert new node ~" << std::endl;
exit(0);
}
node->data = elem;
node->next = cur->next;
cur->next = node;
return 1;
}
int DeleteNode(LinkList list, int index) // 按照对应的链表索引进行删除
{
int len = LinkListLength(list);
if(index < 1 || index > len)
{
std::cout << "Delete node out of range ~" << std::endl;
return 0;
}
Node* cur = list;
for ( int i = 1; i < index; i++) // 找到index节点的前驱节点
{
cur = cur->next;
}
Node* tmp = cur->next;
cur->next = cur->next->next;
free(tmp);
return 1;
}
void ReverseLinkList(LinkList list) // 单链表逆置
{
if (Empty(list) || LinkListLength(list) <= 1)
return;
Node* head = list;
Node* cur = list->next;
Node* next = cur->next; // next 每次都指向待添加的第一个结点
cur->next = NULL; // 置空第一个结点
while(next)
{
cur = next;
next = next->next; // 往后移动还没有添加的指针
cur->next = head->next; // 头部插入取到的新节点 新节点指向头结点后的列表
head->next = cur; // 头结点指向新节点
}
}
LinkList MergeLinkList(LinkList listA, LinkList listB) // 合并两个非升序链表到一个链表 不申请额外空间
{
if (listA == NULL || listB == NULL)
return NULL;
LinkList listC = listA;
Node* pa = listA->next;
Node* pb = listB->next;
free(listB);
listC->next = NULL;
Node* pc = listC;
int x = 0;
while(NULL != pa && NULL != pb)
{
if (pa->data < pb->data)
{
pc->next = pa;
pa = pa->next;
} else if (pa->data > pb->data)
{
pc->next = pb;
pb = pb->next;
} else
{
pc->next = pa;
pa = pa->next;
Node* tmp = pb;
pb = pb->next;
free(tmp);
x++;
}
pc = pc->next;
}
if(pa) pc->next = pa;
if(pb) pc->next = pb;
std::cout << "free node :" << x << std::endl;
return listC;
}
int ExistLoopLinkList(LinkList list) // 判断单链表是否存在环
{
if(NULL == list || list->next == NULL)
return 0;
Node* slow = list;
Node* fast = list;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if (slow == fast)
return 1;
}
return 0;
}
/*
main.cpp
*/
#include "linklist.h"
int main()
{
// test head create linklist
Node* headList = HeadCreateLinkList();
PrintLinkList(headList);
std::cout << "headList length is :" << LinkListLength(headList) << std::endl;
DestoryLinkList(headList);
// test loop linklist
Node* list = TailCreateLinkList();
if (ExistLoopLinkList(list))
std::cout << "List exist loop ~~~" << std::endl;
else
std::cout << "List not exist loop ~~~" << std::endl;
Node* p = list->next->next;
Node* cur = list;
while(p->next)
{
p = p->next;
cur = cur->next;
}
p->next = cur;
if (ExistLoopLinkList(list))
std::cout << "List exist loop ~~~" << std::endl;
else
std::cout << "List not exist loop ~~~" << std::endl;
DestoryLinkList(list);
// test merge 2 linklist
LinkList listA = TailCreateLinkList();
PrintLinkList(listA);
LinkList listB = TailCreateLinkList();
PrintLinkList(listB);
std::cout << "Merge listA and ListB " ;
LinkList ListC = MergeLinkList(listA, listB);
if (NULL != ListC)
{
PrintLinkList(ListC);
}
DestoryLinkList(ListC);
// test reverse linklist
LinkList tailList = TailCreateLinkList();
PrintLinkList(tailList);
std::cout << "tailList length is :" << LinkListLength(tailList) << std::endl;
std::cout << "tailList after reverse:" ;
ReverseLinkList(tailList);
PrintLinkList(tailList);
// test insert and delete elems
std::cout << "Input insert elem and index " << std::endl;
int elem, index;
std::cin >> elem >> index;
if (InsertNode(tailList, elem, index))
{
std::cout << "insert successd and after insert elem : " ;
PrintLinkList(tailList);
}
std::cout << "Input Delete index " << std::endl;
std::cin >> index;
if (DeleteNode(tailList, index))
{
std::cout << "delete successd and after delete elem : " ;
PrintLinkList(tailList);
}
DestoryLinkList(tailList);
return 0;
}