单链表的实现

单链表是数据结构中重要并且基础的一环,学习数据结构就需要知道单链表有的常用操作。

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值