【转】数据结构链表操作之双链表的基本操作

//Node.h 声明类Node
#ifndef Node_H
#define Node_H

template <class T>
class LinkList;       //为是Node类的友员类而声明

template <class T>
class Node
{
   public:        
   friend class LinkList<T>;   //将LinkList类设为友元类
   private:     
   T data;
      Node<T> *next;
};

#endif

===================

//LinkList.h 声明类LinkList
#ifndef LinkQueue_H
#define LinkQueue_H
#include "Node.h"

template <class T>
class LinkList
{
public:
   LinkList( ); //建立只有头结点的空链表
   LinkList(T a[], int n); //建立有n个元素的单链表
   ~LinkList( );          //析构函数
   int Length( );          //求单链表的长度
   T Get(int i);           //取单链表中第i个结点的元素值
   int Locate(T x);       //求单链表中值为x的元素序号
   void Insert(int i, T x);   //在单链表中第i个位置插入元素值为x的结点
   T Delete(int i);        //在单链表中删除第i个结点
   void PrintList( );           //遍历单链表,按序号依次输出各元素
private:
   Node<T> *first; //单链表的头指针
};

#endif
==================

//LinkList.cpp
#include "LinkList.h"
/*
*前置条件:单链表不存在
*输    入:无
*功    能:构建一个单链表
*输    出:无
*后置条件:构建一个单链表
*/
template <class T>
LinkList<T>:: LinkList( )
{
first=new Node<T>; first->next=NULL;
}
/*
*前置条件:单链表不存在
*输    入:顺序表信息的数组形式a[],单链表长度n
*功    能:将数组a[]中元素建为长度为n的单链表
*输    出:无
*后置条件:构建一个单链表
*/
template <class T>
LinkList<T>:: LinkList(T a[ ], int n)
{
    first=new Node<T>;   //生成头结点
Node<T> *r,*s;
     r=first;          //尾指针初始化
    for (int i=0; i<n; i++)
{
      s=new Node<T>; s->data=a[i]; //为每个数组元素建立一个结点
      r->next=s; r=s;      //插入到终端结点之后
}
    r->next=NULL;    //单链表建立完毕,将终端结点的指针域置空
}
/*
*前置条件:无
*输    入:无
*功    能:无
*输    出:无
*后置条件:无
*/
template <class T>
LinkList<T>:: ~LinkList()
{
}
/*
*前置条件:单链表存在
*输    入:查询元素位置i
*功    能:按位查找位置为i的元素并输出值
*输    出:查询元素的值
*后置条件:单链表不变
*/
template <class T>
T LinkList<T>::Get(int i)
{  
Node<T> *p; int j;
p=first->next; j=1; //或p=first; j=0;
while (p && j<i)   
{
    p=p->next;       //工作指针p后移
    j++;
}
if (!p) throw "位置";
else return p->data;
}

/*
*前置条件:单链表存在
*输    入:查询元素值x
*功    能:按值查找值的元素并输出位置
*输    出:查询元素的位置
*后置条件:单链表不变
*/
template <class T>
int LinkList<T>::Locate(T x)
{
Node<T> *p; int j;
p=first->next; j=1;
if(p&&p->next){
   while(p->data!=x)
   {
   p=p->next;
      j++;
   }
return j;
}
else throw "位置";

}

/*
*前置条件:单链表存在
*输    入:插入元素x,插入位置i
*功    能:将元素x插入到单链表中位置i处
*输    出:无
*后置条件:单链表插入新元素
*/
template <class T>
void LinkList<T>::Insert(int i, T x)
{
   Node<T> *p; int j;
   p=first ; j=0;    //工作指针p初始化
   while (p && j<i-1)
   {
     p=p->next;   //工作指针p后移
     j++;
   }
   if (!p) throw "位置";
    else {
   Node<T> *s;
      s=new Node<T>;
   s->data=x; //向内存申请一个结点s,其数据域为x
      s->next=p->next;       //将结点s插入到结点p之后
      p->next=s;
}
}

/*
*前置条件:单链表存在
*输    入:无
*功    能:输出单链表长度
*输    出:单链表长度
*后置条件:单链表不变
*/
template <class T>
int LinkList<T>::Length( )
{
Node <T> *p = first->next;
int i = 0;
while(p)
{
    p = p->next;
    i++;
}
return i;
}
/*
*前置条件:单链表存在
*输    入:要删除元素位置i
*功    能:删除单链表中位置为i的元素
*输    出:无
*后置条件:单链表删除元素
*/
template <class T>
T LinkList<T>::Delete(int i)
{
Node<T> *p; int j;
p=first ; j=0; //工作指针p初始化
while (p && j<i-1) //查找第i-1个结点
{
    p=p->next;
    j++;
}
if (!p || !p->next) throw "位置"; //结点p不存在或结点p的后继结点不存在
    else {
    Node<T> *q; int x;
          q=p->next; x=q->data; //暂存被删结点
          p->next=q->next; //摘链
          delete q;
          return x;
}
}
/*
*前置条件:单链表存在
*输    入:无
*功    能:单链表遍历
*输    出:输出所有元素
*后置条件:单链表不变
*/
template <class T>
void LinkList<T>::PrintList( )
{
Node<T> *p;
p=first->next;
while (p)
{
   cout<<p->data<<endl;
   p=p->next;
}

}

===============

#include<iostream.h>
#include"LinkList.cpp"
#include"Node.h"
void main( )
{

LinkList <int> a;
cout<<"执行插入操作:"<<endl;
try
{
a.Insert(1,4);
a.Insert(2,5);
a.Insert(3,6);
}
catch(char* wrong)
{
   cout << wrong;     //如失败提示失败信息
}
cout<<"已经插入“4,5,6”"<<endl;
cout<<"单链表a的长度为:"<<endl;
cout<<a.Length()<<endl;         //返回单链表长度
cout<<endl;
cout<<"单链表a的元素为:"<<endl;
a.PrintList();                  //显示链表中所有元素
cout<<endl;
cout<<"按位查找第二个元素:"<<endl;
cout<<"第二个元素为:";
cout<<a.Get(2)<<endl;           //查找链表中第二个元素
cout<<endl;
cout<<"按值查找5"<<endl;
cout<<"值为5的元素位置为:";
cout<<a.Locate(5)<<endl;        //查找元素5,并返回在单链表中位置
cout<<endl;
cout<<"执行删除4的操作"<<endl;    
a.Delete(1);                    //删除元素4
cout<<"已删除成功,单链表a的长度为";
cout<<a.Length()<<endl;
cout<<endl;
cout<<"链表a中的元素为:"<<endl;
a.PrintList();

int r[ ]={1,2,3,4,5};
LinkList <int> b(r,5);     //根据数组创建顺序表
cout<<"执行插入操作前单链表b为:"<<endl;
b.PrintList();            //输出单链表所有元素
cout<<"插入前单链表b的长度为:";   
cout<<b.Length()<<endl;
try
{
   b.Insert(3,8);
}
catch(char* wrong)
{
   cout << wrong;     //如失败提示失败信息
}
cout<<"执行插入操作后单链表b为:"<<endl;
b.PrintList();            //输出单链表b所有元素
cout<<"插入后单链表b的长度为:";   
cout<<b.Length()<<endl;
cout<<endl;
try
{
   if(a.Length()){
   cout<<"执行删除第一个元素操作:"<<endl;
   cout<<endl;
   b.Delete(1);                //删除b中第一个元素
      cout<<"已删除成功,单链表b的长度为:";   
      cout<<b.Length()<<endl;
   }

   else{
   cout<<"顺序表b长度为0"<<endl;
   }
}
catch(char* wrong)
{
   cout << wrong;     //如失败提示失败信息
}
cout<<"执行插入操作后单链表b为:"<<endl;
b.PrintList();            //输出单链表所有元素
}

时间: 2024-08-28 12:02:21

【转】数据结构链表操作之双链表的基本操作的相关文章

Java 数据结构链表操作实现代码_java

 链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表.循环链表.双向链表,下面将逐一介绍.链表在数据结构中是基础,也是重要的知识点,这里讲下Java 中链表的实现, JAVA 链表操作:单链表和双链表 主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都相应的应用,链表有多种类别,文章针对单链表和双链表进行分析.链表中数据就像被一个

JAVA 数据结构链表操作循环链表_java

JAVA 链表操作:循环链表 主要分析示例: 一.单链表循环链表 二.双链表循环链表 其中单链表节点和双链表节点类和接口ICommOperate<T>与上篇一致,这里不在赘述.参考:JAVA链表操作:单链表和双链表http://www.jb51.net/article/95113.htm 一.单链表循环链表 package LinkListTest; import java.util.HashMap; import java.util.Map; public class SingleCycle

简单介绍线性表以及如何实现双链表_java

线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列. 一.数组数组有上界和下界,数组的元素在上下界内是连续的. 存储10,20,30,40,50的数组的示意图如下: 数组的特点:数据是连续的:随机访问速度快. 数组中稍微复杂一点的是多维数组和动态数组.对于C语言而言,多维数组本质上也是通过一维数组实现的.至于动态数组,是指数组的容量能动态增长的数组:对于C语言而言,若要提供动态数组,需要手动实现:而对于C++而言,STL提供了Vector:对于Java而言,Collec

c++-请大家帮我看下这段实现链表操作的C++的代码。

问题描述 请大家帮我看下这段实现链表操作的C++的代码. push_front这个操作有问题. #include <iterator> using namespace std; template <typename T> class List{ struct node{ node() = default; node(const T& x, node *y=nullptr) :m_data(x), m_next(y) {} T m_data; node *m_next; };

c++ delphi 回调函数-一个数据结构的题目,涉及Hash、双链表、回调函数等,求大神指教?

问题描述 一个数据结构的题目,涉及Hash.双链表.回调函数等,求大神指教? 数据结构相关的题目描述 typedef?struct?_FILE_NODE?{ _FILE_NODE?*Prev; _FILE_NODE?*Next; WCHAR?wzFileName[MAX_PATH]; DWORD?dwLowDateTimeLastWrite; }?FILE_NODE,?*LPFILENODE; 实现两个项目: 一.DLL 1.实现文件遍历的功能 2.导出接口中,可由用户指定遍历哪个文件夹 3.提

javascript数据结构之双链表插入排序实例详解_javascript技巧

本文实例讲述了javascript数据结构之双链表插入排序实现方法.分享给大家供大家参考,具体如下: 数组存储前提下,插入排序算法,在最坏情况下,前面的元素需要不断向后移,以便在插入点留出空位,让目标元素插入. 换成链表时,显然无需做这种大量移动,根据每个节点的前驱节点"指针",向前找到插入点后,直接把目标值从原链表上摘下,然后在插入点把链表断成二截,然后跟目标点重新接起来即可. <!doctype html> <html> <head> <t

数据结构之自建算法库——双链表

本文针对数据结构基础系列网络课程(2):线性表中第12课时双链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:dlinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef DLINKLIST_H_INCLUDED #define DLINKLIST_H_INCLUDED typedef int ElemType; typedef s

数据结构之自建算法库——循环双链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时循环链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:cdlinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CDLINKLIST_H_INCLUDED #define CDLINKLIST_H_INCLUDED //循环双链表基本运算函数 typedef int E

数据结构实践——循环双链表应用

本文针对数据结构基础系列网络课程(2):线性表的实践项目. [项目- 循环双链表应用] 设非空线性表ha和hb都用带头节点的循环双链表表示.设计一个算法Insert(ha,hb,i).其功能是:i=0时,将线性表hb插入到线性表ha的最前面:当i>0时,将线性表hb插入到线性表ha中第i个节点的后面:当i大于等于线性表ha的长度时,将线性表hb插入到线性表ha的最后面. 请在实现算法时,除项目中给出的特殊要求,其余工作均可利用项目4完成的算法支持. [参考解答](循环双链表的基本运算算法,请参考