双向链表的实现

双向链表的实现

1> 头插式双向链表的创建

2> 尾插式双向链表的创建

3> 双向链表长度

4> 打印双向链表

5> 释放双向链表

6> 查找指定节点

7> 在指定元素之前插入新节点

8> 删除指定节点

9> 双向链表的逆置

/*
  dulinklist.h
*/

#include <iostream>

typedef struct DuNode
{
  int data;
  DuNode* prior;
  DuNode* next;
};

typedef DuNode* DuLinkList;

// 头插式创建单头双向链表
DuLinkList HeadCreateDuLinkList()
{
  DuNode* head = (DuNode*) malloc(sizeof(DuNode));
  if (NULL == head)
  {
    std::cout << "Head create dulinklist for head node failed " << std::endl;
    exit(0);
  }

  head->prior = NULL;
  head->next = NULL;

  DuNode* cur = head;
  DataType tmp;

  std::cout << "Input DuLinkList elems and -1 end ~" << std::endl;
  while(std::cin >> tmp)
  {
    if ( -1 == tmp ) break;

    DuNode* node = (DuNode*) malloc(sizeof(DuNode));
    if ( NULL  == node )
    {
      std::cout << "Head create dulinklist for elem node failed " << std::endl;
      exit(0);
    }

    node->data = tmp;
   
    node->next = cur->next;
    if (NULL != cur->next)
    {
      cur->next->prior = node;
    }

    node->prior = cur;
    cur->next = node;
  }
  
  return head;
}

// 尾插式创建单头双向链表
DuLinkList TailCreateDuLinkList()
{

  DuNode* head = (DuNode*) malloc(sizeof(DuNode));
  if (NULL == head)
  {
    std::cout << "Tail create dulinklist for head node failed " << std::endl;
    exit(0);
  }

  head->prior = NULL;
  head->next = NULL;

  DuNode* cur = head;
  DataType tmp;

  std::cout << "Input DuLinkList elems and -1 end ~" << std::endl;
  while(std::cin >> tmp)
  {
    if ( -1 == tmp ) break;

    DuNode* node = (DuNode*) malloc(sizeof(DuNode));
    if ( NULL  == node )
    {
      std::cout << "Tail create dulinklist for elem node failed " << std::endl;
      exit(0);
    }

    node->data = tmp;

    node->next = NULL;
    node->prior = cur;
    cur->next = node;
    cur = node;
  }

  return head;
}

int LengthDuLinkList(DuLinkList list)
{
  int len = -1;
  DuNode* ptr = list;
  while(NULL != ptr)
  {
    len++;
    ptr = ptr->next;
  }
  return len;
}

// 打印双向链表
void PrintDuLinkList(DuLinkList list)
{
  DuNode* cur = list->next;     // 指向第一个node节点
  std::cout << "DuLinkList elems :[";
  while(cur)
  {
    std::cout << " " << cur->data;
    cur = cur->next;
  }
  std::cout << " ]" << std::endl;
}

// 释放双向链表
void DestoryDuLinkList(DuLinkList list)
{
  DuNode* cur = list;
  DuNode* tmp;
  while(cur)
  {
    tmp = cur->next;
    free(cur);
    cur = tmp;
  }
}

// 在双向链表中查找值为val的node,找不到返回NULL
DuNode* FindDuNode(DuLinkList list, DataType val)
{
  DuNode* cur  = list->next;
  while(cur)
  {
    if (cur->data == val)
      return cur;
    cur = cur->next;
  }
  return NULL;
}

// 在双向链表节点值为val的节点前插入elem的节点,正常插入返回1 否则返回0
int InsertDuNode(DuLinkList list , DataType val, DataType elem)
{
  DuNode* cur = list->next;
  while(cur)        // 查找对应的val结点,这里不调用FindDuNode函数
  {
    if (cur->data == val)
     break;
    cur = cur->next;
  }

  if (NULL == cur) return -1;

   DuNode* node = (DuNode*) malloc(sizeof(DuNode));
   node->data = elem;
   
    node->prior = cur->prior;
    cur->prior->next = node;
    node->next = cur;
    cur->prior = node;

    return 1;
}

// 从双向链表中删除值为val的第一个节点 如果没有返回-1,删除成功返回1 否则返回0
int DeleteDuNode(DuLinkList list, DataType val)
{
  DuNode* node = FindDuNode(list, val);
  if (NULL == node) return -1;

  node->prior->next = node->next;
  
  if (NULL != node->next)
  node->next->prior = node->prior;
  free(node);

  return 1;
}

void ReverseDuLinkList(DuLinkList list)
{
  if (LengthDuLinkList(list) < 2)    // 保证链表至少有两个节点 逆置才有意义 避免后期的判断
    return;

  DuNode* cur;
  DuNode* next;
  DuNode* head = list;
  cur = head->next;   // cur 当前指向第一个结点
  next = cur->next;   // next 指向第一个需要逆置的节点
  cur->next = NULL;   // 逆置结束第一个节点将变成最后尾节点
  
  while(next)
  {
    cur = next;
    next = next->next;

    cur->next = head->next;
    head->next->prior = cur;
    cur->prior = head;
    head->next = cur;
  }
}

/*
    main.cpp
*/

#include "dulinklist.h"

int main()
{
  //  test head create dulinklist
  DuLinkList hlist = HeadCreateDuLinkList();
  PrintDuLinkList(hlist);
  DestoryDuLinkList(hlist);

  //  test tail create dulinklist
  DuLinkList tlist = TailCreateDuLinkList();
  PrintDuLinkList(tlist);
  DestoryDuLinkList(tlist);

  DuLinkList list = TailCreateDuLinkList();
  PrintDuLinkList(list);
  std::cout << "DuLinkList length :" << LengthDuLinkList(list) << std::endl; 

  // test reverse
  ReverseDuLinkList(list);
  PrintDuLinkList(list);

  //   test find node
  std::cout << "Input the val for find" << std::endl;
  DataType val;
  std::cin >> val;
  DuNode* node = FindDuNode(list, val);
  if (NULL != node)
  {
    std::cout << "Find it and " << node->data << std::endl;
  }
  else{
    std::cout << "Not Find " << std::endl;
  }

  // test insert node
  DataType elem;
  std::cout << "Input the val and elem for insert" << std::endl;
  std::cin >> val >> elem;

  if (1 == InsertDuNode(list, val, elem))
  {
    std::cout << "Insert successd ";
    PrintDuLinkList(list);
  }else{
    std::cout << "Insert failed " << std::endl;
  }

  // test delete
  std::cout << "Input the val of delete" << std::endl;
  std::cin >> val ;

  if (1 == DeleteDuNode(list, val))
  {
    std::cout << "delete successd ";
    PrintDuLinkList(list);
  }else{
    std::cout << "delete failed " << std::endl;
  }

  DestoryDuLinkList(list);
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值