在n个结点的顺序表中插入一个结点需平均移动几个结点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在n个结点的顺序表中插入一个结点需平均移动几个结点相关的知识,希望对你有一定的参考价值。

已经有N个点了,再加一个就是N+1个。假设新加的结点插在第i位,那么后面N+1-i个结点都要往后移动。

期望有计算公式,这里等于(N+1-1)*1/(N+1)+(N+1-2)*1/(N+1)+(N+1-3)*1/(N+1)+...+(N+1-N-1)*1/(N+1)=N/2。

i的取值服从1到N+1的平均分布,即概率是1/(N+1)。


扩展资料:

包括一个数据元素及若干个指向其它子树的分支;例如,A,B,C,D等。在数据结构的图形表示中,对于数据集合中的每一个数据元素用中间标有元素值的方框表示,一般称之为数据结点,简称结点。

在C语言中,链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据;二为下一个结点的地址,即指针域和数据域。

数据结构中的每一个数据结点对应于一个储存单元,这种储存单元称为储存结点,也可简称结点。

参考资料来源:百度百科-结点

参考技术A 讲期望未必麻烦了一点。
通俗的来说:有n个结点,即有n+1个位置可以插入。插在最后空位,需要移动的次数为0;插在第一个,需要移动的次数为n,等差数列求和,得到一共可能移动的总次数为(n*(n+1))/2。再除以n+1个位置,则平均需要移动的点为n/2。
参考技术B 插入到第一个节点前面是n次,插入到第一个节点后面是n-1次。。。插入到最后一个节点后面是0次故(n+0)*n/2 参考技术C 是n/2,具体移动的元素个数与表长和该元素 在表中的位置有关。 参考技术D 最少0, 最大n , 线性, 所以平均是 (0+n)/2 = n/2

线性表顺序存储

# 线性表顺序存储

我们来谈一下线性表的顺序储存结构

图示:
技术图片

  • 定义:

    • 由 n (n>=0)个数据特性相同的元素构成的有限序列称为线性表
    • 线性表中元素的个数 n (n>=0)定义为线性表的长度,n = 0 时称为空表

  • 特点:

    • 而对于一个非空的线性表来说,通常具有以下特征

      1、存在 唯一 的开始结点
      2、存在 唯一 的终端结点
      3、 除了终端结点和开始结点,其间的每一个结点都有 一个直接前驱一个直接后继

    • 逻辑结构:线性结构
    • 特点:类型相同、有限性、有序性
    • 也是应用最广泛的数据结构之一

顺序储存:

  • 线性表的顺序表示指的是用一组 地址连续的存储单元 依次 存储线性表的数据元素,这种表示也称作线性表的 顺序存储顺序映像

图例:
技术图片


C++实现代码

  • main.cpp
#include"LinkListHead.h"
void menu();
int main()

    char choise;
    LinkList ElemList;
    menu();
    std::cout << "请输入你的选择" << std::endl;
    std::cin >> choise;
    switch (choise)
    
    case '1':
        if (ElemList.Create())
        
            if (!ElemList.Insert(100, 5))
            
                std::cout << "不能插入100到5的位置是因为该表已满" << std::endl;
                ElemList.DisplayList();
            
        
        break;
    case '2':
        if (ElemList.Create())
        
            if (!ElemList.Delete(3))
            
                std::cout << "不能删除的原因是因为表为空或者没有该下标" << std::endl;
                ElemList.DisplayList();
            
        
        break;
    case '3':
        if (ElemList.Create())
        
            if (ElemList.Insert(100, 6))
            
                std::cout << "能插入是因为其中元素个数为5个" << std::endl;
                ElemList.DisplayList();
            
        
        break;
    case '4':
        if (ElemList.Create())
        
            if (!ElemList.Insert(100, 7))
            
                std::cout << "不能插入是因为该元素个数只有5个,无法在第七个位置插入一个数"
                    << std::endl;
                ElemList.DisplayList();
            
        
        break;
    case '5':
        if (ElemList.Create())
        
            if (ElemList.Delete(4))
            
                std::cout << "能删除是因为列表中有大于4个元素的个数" << std::endl;
                ElemList.DisplayList();
            
        
        break;
    case '6':
        if (ElemList.Create())
        
            if (!ElemList.Delete(8))
            
                std::cout << "不能在第8个位置删除的原因是列表中没有大于或等于8的个数"
                    << std::endl;
                ElemList.DisplayList();
            
        
        break;
    case '7':
        if (ElemList.Create())
        
            if (ElemList.Insert(100, 1))
            
                std::cout << "能在该位置插入的原因是改下标合法" << std::endl;
                ElemList.DisplayList();
            
        
        break;
    case '8':
        if (ElemList.Create())
        
            if (ElemList.Delete(1))
            
                std::cout << "该位置能够删除是因为该下标处于线性表长度中" << std::endl;
                ElemList.DisplayList();
            
        
        break;
    default:
        std::cout << "非法输入,结束" << std::endl;
        break;
    
    return 0;


void menu()

    std::cout
        <<"1、申请10个空间,往空间中放进10个元素,然后随意增加一个元素\\n" 
        <<"2、申请10个空间,往空间中放进0个元素,然后随意删除一个元素\\n"
        <<"3、申请10个空间,往空间中放进5个元素,然后在第6个位置增加一个元素\\n"
        <<"4、申请10个空间,往空间中放进5个元素,然后在第7个位置增加一个元素\\n"
        <<"5、申请10个空间,往空间中放进5个元素,然后删除第4个位置的元素\\n"
        <<"6、申请10个空间,往空间中放进5个元素,然后删除第8个位置的元素\\n"
        <<"7、申请10个空间,往空间中放进0个元素,然后增加第1个位置的元素\\n"
        <<"8、申请10个空间,往空间中放进5个元素,然后删除第1个位置的元素\\n"
        <<std::endl;

  • LinkListHead.h
#pragma once
#ifndef _LINKLISTHEAD_H_
#define _LINKLISTHEAD_H_
#include<iostream>
#include<cstdlib>
typedef int DataType;
class LinkList

private:
    int length;//表元素的长度
    int maxsize;//表最大的长度
    bool empty;//判断表空
    DataType* list = nullptr;//表
public:
    LinkList();//初始化函数,初始化为空表 done
    LinkList(LinkList& L);//构造一个新的线性表 done
    bool Create();//创建顺序离散表 done
    bool Insert(DataType target, int index);//往第几个位置插入一个元素 done
    bool Delete(int index);//删除下标为index的元素 done
    int Find(DataType target);//找到是否有这些元素,然后返回该元素下标,如果没有,返回0
    void DisplayList();//显示线性表
    void DestoryList();//摧毁离散表
    virtual ~LinkList();//析构链表

;
#endif // !_LINKLISTHEAD_H_
  • LinkListHead.cpp
#include "LinkListHead.h"

LinkList::LinkList()

    length = 0;
    maxsize = 0;
    empty = true;


LinkList::LinkList(LinkList& L)

    length = L.length;
    maxsize = L.maxsize;
    empty = L.empty;
    //进行拷贝复制,申请新的顺序表
    list = new DataType[maxsize];//申请maxsize大小的空间
    for (int i = 0; i < length; i++)//进行每一个元素复制
        list[i] = L.list[i];



bool LinkList::Create()

    using std::cin;
    using std::cout;
    using std::endl;
    cout << "请输入申请顺序线性表的大小" << endl;
    cin >> maxsize;//输入线性表的大小
    list = new DataType[maxsize];//利用大小来创建线性表
    if (!list)//如果表为空
    
        cout << "不能申请空间" << endl;
        exit(-1);//当申请空间失败的时候,退出
    
    //当表空的时候,创建数据
    cout << "请输入有多少个数据" << endl;
    cin >> length;
    if (length<0 || length>maxsize)
    
        cout << "非法输入创建失败" << endl;
        //失败后置空空间,恢复初始设置
        maxsize = 0;
        length = 0;
        delete[]list;
        list = nullptr;

        return false;//返回失败
    
    else
    
        cout << "请输入数据" << endl;
        for (int i = 0; i < length; i++)
            cin >> list[i];//进行数据输入
        cout << "输入成功,创建成功" << endl;
        empty = false;
        return true;//返回成功
    


bool LinkList::Insert(DataType target, int index)

    using std::cout;
    using std::endl;
    //首先进行非法检查
    if (index<1 || index>length+1 || length == maxsize)//判断插入数的下表是否是合法
    
        //非法的形式:
        //1、插入的下表上溢或者下溢
        //2、顺序表中的元素的长度已经等于最大值的长度
        cout << "非法插入" << endl;
        return false;
    
    else
    
        for (int i = length - 1; i >= index - 1; i--)
        
            list[i + 1] = list[i];//整体元素往后移动一位
        
        list[index - 1] = target;//把index位置插入元素
        length++;
        cout << "插入成功" << endl;
        return true;
    


bool LinkList::Delete(int index)

    using std::endl;
    using std::cout;
    if (length == 0 || empty)
    
        cout << "表空,无法删除" << endl;
        return false;
    
    if (index<1 || index>length)
    
        //大于有效长度,或者小于最小长度,非法
        cout << "非法下标" << endl;
        return false;
    
    else
    
        //如果不是以上的情况,那么正常删除其中的元素
        
        for (int i = index - 1; i < length; i++)
            list[i] = list[i + 1];//后一位赋值给前一位,覆盖掉前一位
        length--;//长度减少1
        cout << "删除完成" << endl;
        return true;//返回成功
    


int LinkList::Find(DataType target)

    for (int i = 0; i < length; i++)
        if (list[i] == target)
            return i + 1;//找到了,返回其元素的下表
    return 0;//找不到,返回0


void LinkList::DisplayList()

    for (int i = 0; i < length; i++)
    
        std::cout << list[i] << " ";
    
    std::cout << "length = "<<length << std::endl;
    std::cout << std::endl;


void LinkList::DestoryList()

    delete[]list;
    length = 0;
    maxsize = 0;
    list = nullptr;


LinkList::~LinkList()

    delete[]list;
    length = 0;
    maxsize = 0;
    list = nullptr;


运行图示:

菜单1:
技术图片

菜单2:
技术图片

菜单3:
技术图片

菜单4:
技术图片

菜单5:
技术图片

菜单6:
技术图片

菜单7:
技术图片

菜单8:
技术图片

以上便是全部代码,如有错误,请指出。

借鉴书籍《数据结构 c语言第二版》

以上是关于在n个结点的顺序表中插入一个结点需平均移动几个结点的主要内容,如果未能解决你的问题,请参考以下文章

数据结构链表练习题

链表中倒数第k个结点

单链表实现“插入”和“删除”操作

数据结构 c语言版 ——顺序表的查找、插入与删除

单链表的简单实现

什么是链表?