欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來到入門教程網(wǎng)!

C語言

當前位置:主頁 > 軟件編程 > C語言 >

C++ 雙鏈表的基本操作(詳解)

來源:本站原創(chuàng)|時間:2020-01-10|欄目:C語言|點擊: 次

1.概念

雙向鏈表也叫雙鏈表,是鏈表的一種,它的每個數(shù)據(jù)結點中都有兩個指針,分別指向直接后繼和直接前驅。所以,從雙向鏈表中的任意一個結點開始,都可以很方便地訪問它的前驅結點和后繼結點。一般我們都構造雙向循環(huán)鏈表。

結構圖如下所示:

  

  

2.基本操作實例

DoubleList.cpp

#include "stdafx.h"
#include "DoubleList.h"
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
DoubleList::DoubleList()
{
    pDoubleListNode pDouList = NULL;
    // 創(chuàng)建雙鏈表
    CreateDouList(pDouList);
    PrintDouList(pDouList);
    // 打印逆序鏈表
    PrintDouReverseList(pDouList);
    // 節(jié)點后插入節(jié)點
    InsertNodeAfter(pDouList);
    PrintDouList(pDouList);
    // 節(jié)點前插入節(jié)點
    InsertNodeBefore(pDouList);
    PrintDouList(pDouList);
    // 刪除節(jié)點
    DeleteNode(pDouList);
    PrintDouList(pDouList);
    // 刪除鏈表
    DeleteDouList(pDouList);
    PrintDouList(pDouList);
    system("PAUSE");
}
DoubleList::~DoubleList()
{
}
//創(chuàng)建雙向鏈表
void DoubleList::CreateDouList(pDoubleListNode &head)
{
  char x;     // 定義成char型是用于輸入'q'時可以退出,其實定義成int也能退出
  pDoubleListNode p, s;
  head = (pDoubleListNode)malloc(sizeof(DoubleListNode));
  head->next = NULL;
  head->prior = NULL;    // 構造頭結點p
  p = head;
  printf("\n輸入雙向鏈表的元素,每輸入一個元素后按回車,輸入q表示結束.\n");
  fflush(stdin);  //清空輸入緩沖區(qū)
  x = getchar();
  while (x != 'q')
  {
    s = (pDoubleListNode)malloc(sizeof(DoubleListNode));
    s->data = x - '0'; // 得到的是輸入字符的ASCII碼,減去30H就變成想要的數(shù)字
    s->next = NULL;
    s->prior = p;
    p->next = s;
    p = s;
    fflush(stdin);
    x = getchar();
  }
  if (x == 'q')
  {
    printf("雙向鏈表構造完畢!\n");
  }
}
//打印雙向鏈表
void DoubleList::PrintDouList(pDoubleListNode &head)
{
  pDoubleListNode p;
  printf("\n打印出雙向鏈表數(shù)據(jù)為:\n");
  if (!IsDouListEmpty(head))
  {
    p = head->next;
    while (p)
    {
      printf("%d\n", p->data);
      p = p->next;
    }
  }
}
//逆序打印雙向鏈表
void DoubleList::PrintDouReverseList(pDoubleListNode &head)
{
  pDoubleListNode p;
  printf("\n打印出逆序雙向鏈表數(shù)據(jù)為:\n");
  if (!IsDouListEmpty(head))
  {
    p = head->next;
    while (p->next)
    {
      p = p->next;
    }
    while (p->prior)
    {
      printf("%d \n", p->data);
      p = p->prior;
    }
  }
}
//求鏈表長度
int DoubleList::GetDouListLength(pDoubleListNode &head)
{
  int length = 0;
  if (head == NULL)
  {
    printf("鏈表不存在,請先初始化!\n");
  }
  else
  {
    pDoubleListNode p = head->next;
    while (p)
    {
      length++;
      p = p->next;
    }
  }
  return length;
}
//判斷鏈表是否為空
bool DoubleList::IsDouListEmpty(pDoubleListNode &head)
{
  if (head == NULL)
  {
    printf("鏈表不存在,請先初始化!\n");
    return true;
  }
  else if (head->next == NULL)
  {
    printf("鏈表為空!\n");
    return true;
  }
  
  return false;
}
//把雙向鏈表置空
void DoubleList::ClearDouList(pDoubleListNode &head)
{
  if (head == NULL)
  {
    printf("鏈表不存在,請先初始化!\n");
  }
  else
  {
    pDoubleListNode p, q;
    p = q = head->next;  //是p、q指向第一個元素
    head->next = NULL;
    while (p)     //逐個釋放元素所占內存
    {
      p = p->next;
      free(q);
      q = p;
    }
  }
}
// 刪除雙向鏈表
void DoubleList::DeleteDouList(pDoubleListNode &head)
{
  printf("\n刪除雙向鏈表\n");
  ClearDouList(head);
  free(head);
  head = NULL;
}
// 在雙向鏈表中第i個位置后面插入元素
void DoubleList::InsertNodeAfter(pDoubleListNode &head)
{
  int data, pos;
  pDoubleListNode p, s;
  p = head;
  int i = 0;
  printf("\n在雙向鏈表中第i個位置后面插入元素\n");
  printf("請輸入要插入的元素和位置:\n");
  scanf_s("%d%d", &data, &pos, 100);
  if (head == NULL)
  {
    printf("鏈表不存在,請先初始化!\n");
  }
  else if (head->next == NULL)
  {
    printf("鏈表為空,插入第一個元素!\n");
    s = (pDoubleListNode)malloc(sizeof(DoubleListNode));
    s->data = data;
    s->prior = NULL;  
    s->next = NULL;
    head->next = s;    // 將新結點插入head后 
  }
  else if (pos<1 || pos>GetDouListLength(head) + 1)
  {
    printf("插入位置錯誤!\n");
  }
  else
  {
    while (i < pos)
    {
      p = p->next;
      i++;
    }
    if (i == GetDouListLength(head))   //如果在最后一個元素后面插入data
    {
      s = (pDoubleListNode)malloc(sizeof(DoubleListNode));
      s->data = data;
      s->next = NULL;
      s->prior = p;
      p->next = s;
    }
    else
    {
      s = (pDoubleListNode)malloc(sizeof(DoubleListNode));
      s->data = data;
      s->next = p->next;
      p->next->prior = s;
      p->next = s;
      s->prior = p;
    }
  }
}
// 在雙向鏈表中第i個位置前面插入元素
void DoubleList::InsertNodeBefore(pDoubleListNode &head)
{
  int data, pos;
  pDoubleListNode p, s;
  p = head;
  int i = 0;
  printf("\n在雙向鏈表中第i個位置前面插入元素\n");
  printf("請輸入要插入的元素和位置:\n");
  scanf_s("%d%d", &data, &pos, 100);
  if (head == NULL)
  {
    printf("鏈表不存在,請先初始化!\n");
  }
  else if (head->next == NULL)
  {
    printf("鏈表為空,插入第一個元素!\n");
    s = (pDoubleListNode)malloc(sizeof(DoubleListNode));
    s->data = data;
    s->prior = NULL;
    s->next = NULL;
    head->next = s;    // 將新結點插入head后 
  }
  else if (pos<1 || pos>GetDouListLength(head) + 1)
  {
    printf("插入位置錯誤!\n");
  }
  else
  {
    while (i < pos)
    {
      p = p->next;
      i++;
    }
    if (i == 1)   // 如果在第一個元素前面插入data
    {
      s = (pDoubleListNode)malloc(sizeof(DoubleListNode));
      s->data = data;
      head->next = s;    // 將新結點插入head后 
      s->prior = head;    // 新結點的前結點指向頭結點 
      s->next = p;            // 新結點的后結點指向原h(huán)ead的后結點 
      p->prior = s ;          // 原第一個結點的前結點指向新結點 
    }
    else
    {
      s = (pDoubleListNode)malloc(sizeof(DoubleListNode));
      s->data = data;
      s->prior = p->prior;
      s->next = p;
      p->prior->next = s;
      p->prior = s;
    }
  }
}
//刪除雙向鏈表中的第i個元素
void DoubleList::DeleteNode(pDoubleListNode &head)
{
  int pos;
  int i = 0;
  pDoubleListNode p = head;
  printf("\n在雙向鏈表中刪除第i個位置的元素\n");
  printf("請輸入要刪除的位置:");
  scanf_s("%d", &pos, 100);
  
  if (IsDouListEmpty(head))
  {
    return;
  }
  else if (pos<1 || pos>GetDouListLength(head))
  {
    printf("刪除的位置不存在!\n");
  }
  else
  {
    while (i < pos)
    {
      p = p->next;
      i++;
    }
    if (i == GetDouListLength(head))
    {
      p->prior->next = NULL;
      free(p);
    }
    else
    {
      p->prior->next = p->next;
      p->next->prior = p->prior;
      free(p);
    }
  }
}

DoubleList.h

#pragma once
typedef struct DoubleListNode
{
  int data;       //數(shù)據(jù)
  struct DoubleListNode *prior; //前驅
  struct DoubleListNode *next; //后繼
}DoubleListNode, *pDoubleListNode;
class DoubleList
{
public:
  DoubleList();
  ~DoubleList();
  //初始化雙向鏈表
  void DoubleList::CreateDouList(pDoubleListNode &head);
  //打印雙向鏈表
  void DoubleList::PrintDouList(pDoubleListNode &head);
  //逆序打印雙向鏈表
  void DoubleList::PrintDouReverseList(pDoubleListNode &head);
  //求鏈表長度
  int DoubleList::GetDouListLength(pDoubleListNode &head);
  //判斷鏈表是否為空
  bool DoubleList::IsDouListEmpty(pDoubleListNode &head);
  //把雙向鏈表置空
  void DoubleList::ClearDouList(pDoubleListNode &head);
  //刪除雙向鏈表
  void DoubleList::DeleteDouList(pDoubleListNode &head);
  //在雙向鏈表中第i個位置后面插入元素m
  void DoubleList::InsertNodeAfter(pDoubleListNode &head);
  // 在雙向鏈表中第i個位置前面插入元素
  void DoubleList::InsertNodeBefore(pDoubleListNode &head);
  //刪除雙向鏈表中的第i個元素
  void DoubleList::DeleteNode(pDoubleListNode &head);
};

3.對鏈表插入節(jié)點的理解

例如在節(jié)點i前插入一個新的節(jié)點(即上面代碼中的InsertNodeBefore函數(shù)):

鏈表結構體為:
typedef struct DoubleListNode
{
  int data;       // 數(shù)據(jù)
  struct DoubleListNode *prior; // 前驅
  struct DoubleListNode *next; // 后繼
}DoubleListNode, *pDoubleListNode;

假設該鏈表由五個節(jié)點構成,分別為A,B,C,D,E

  

圖中假設了A,B,C,D,E的地址分別為:addressA,addressB,addressC,addressD,addressE。

下面將分析鏈表的前插的例子:

雙鏈表的前插,下面這是在節(jié)點"D"前插入一個新的節(jié)點"S"的代碼和分析

s = (pDoubleListNode)malloc(sizeof(DoubleListNode));  // 申請一段內存空間,指針指向首地址為addressS
s->data = data;     // 給節(jié)點S的數(shù)據(jù)賦值data
s->prior = p->prior;  // p指向D節(jié)點, p->prior表示addressC,將它賦給s->prior,則s->prior里面的值是addressC,從而指向addressC這個地址即節(jié)點C,如下圖S節(jié)點的藍線
s->next = p;      // p是addressD,將它賦給s->next,s->next中的值為addressD,也即s->next指向了D,如下圖S節(jié)點的紅線
p->prior->next = s;  // p->prior 是addressC,即節(jié)點C,所以p->prior->next相當于沒插入S之前的addressD,插入S后,將S的首地址即addressS賦給這個位置,所以此時,由CD的紅線斷裂,這個紅線目標變成了S,如下圖C節(jié)點的紅線
p->prior = s;     // 同理,p->prior也指向了S,即p->prior中addressC變成了addressS, D指向C的藍線斷裂。變成如下圖D節(jié)點指向S節(jié)點的藍線.

以上這篇C++ 雙鏈表的基本操作(詳解)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持我們。

上一篇:stringstream操縱string的方法總結

欄    目:C語言

下一篇:C++中4種強制類型轉換的區(qū)別總結

本文標題:C++ 雙鏈表的基本操作(詳解)

本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/1930.html

網(wǎng)頁制作CMS教程網(wǎng)絡編程軟件編程腳本語言數(shù)據(jù)庫服務器

如果侵犯了您的權利,請與我們聯(lián)系,我們將在24小時內進行處理、任何非本站因素導致的法律后果,本站均不負任何責任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權所有