精华内容
下载资源
问答
  • 答:嗯,我觉得顺序表嘛,给定的数据不一定按照从小到大或者从大到小的顺序排序,可以随机的数;但是有序表就不一样了哦,它里面的数据一定按照某种标准排序好了,否则怎么叫有序表呢?是不是。 问:嗯嗯,我...

    什么是顺序表?

    就我的理解,顺序表其实是一个数组,只不过这个数组是被封装在一个结构体中的。所以它也算是线性表的一种哦。

    顺序表跟有序表的区别?

    我觉得顺序表嘛,给定的数据不一定是按照从小到大或者从大到小的顺序排序,可以是随机的数;但是有序表就不一样了哦,它里面的数据一定是按照某种标准排序好了,否则怎么叫有序表呢?是不是。

    之前我们说过,顺序表是在计算机内存中以数组的形式保存的线性表,因此呢,我们要先定义一个结构体:

    typedef struct
    {
    	ElementType elem[MAXSIZE];/* 静态申请 */
    	int length;/* 当前长度 */
    }SeqList;
    

    这个静态申请是什么意思?

    这个嘛~就是申请一段静态的内存啦,数组学过吧,静态数组里面分配的都是一段连续的存储空间。我们先给这个顺序表初始化一下:

    void CreateList(SeqList *L)/* 创建顺序表 */
    {
    	int i;
    	L->length = 0;
    	printf("Enter the length of the sequence table:");
    	scanf("%d",&L->length);
    	if(L->length == 0) return;
    	printf("Enter the elements of the sequence table:\n");
    	for(i = 0;i < L->length;i++)
    	{
    		scanf("%d",&L->elem[i]);
    	}
    }
    

    要注意哦,我是在创建的时候初始化,因此可以省略掉长度为0以及数组里面数据为0的定义。

    下面我们来进行一下判空操作,这一步很简单:

    bool IsListEmpty(SeqList *L)/* 判断为空 */
    {
    	if(L == NULL || L->length == 0) return true;
    	else return false;
    }
    

    注意是判断是否为空,所以为空返回真。

    接下来是遍历顺序表的操作:

    bool TraverseList(SeqList *L)/* 遍历顺序表并输出 */
    {
    	int i;
    	if(IsListEmpty(L) == true) return false;/* 如果为空,返回错误 */
    	else/* 否则,按照下标顺序输出 */
    	{
    		for(i = 0;i < L->length;i++)
    		{
    		    printf("%d\t",L->elem[i]);
    		}
    		printf("\n");
    	}
    	return true;
    }
    

    如何按位置插入元素呢:

    bool InsertListElement(SeqList *L,int i,ElementType e)/* 在第i个位置插入元素e */
    {
    	if(IsListEmpty(L) == true || L->length == MAXSIZE || i < 0 || i > L->length)
    		return false;/* 表空表满,i的位置不合适都返回错误 */
    	else
    	{
    		for(int j = ++L->length;j >= i;j--)
    		{
    			L->elem[j] = L->elem[j - 1];/* 第i-1个位置之后的数据都后移一位  */
    		}
    		L->elem[i - 1] = e;
    	}
    	return true;
    }
    

    求顺序表的长度:

    int LengthList(SeqList *L)/* 求顺序表表长 */
    {
    	if(IsListEmpty(L) == true) return 0;
    	else printf("%d",L->length);
    }
    

    顺序表的逆置,类似于一维数组的逆序输出操作:

    bool InversionList(SeqList *L)/* 顺序表的逆置 */
    {
    	if(IsListEmpty(L) == true || L->length == 1) return false;
    	else
    	{
    		for(int i=0;i < L->length / 2;i++)
    		{
    			LIST_SWAP(L->elem[i],L->elem[L->length - i - 1]);
    		}
    	}
    	return true;
    }
    

    排序顺序表:

    bool SortList(SeqList *L,bool style)/* 排序顺序表,style为真表示从小到大,反之从大到小 */
    {
    	if(IsListEmpty(L) == true) return false;
    	else
    	{
    		for(int i = 0;i < L->length;i++)
    		{
    			for(int j = 0;j < i;j++)
    			{
    				if(style == true && L->elem[j] > L->elem[j + 1]) 
    					LIST_SWAP(L->elem[j],L->elem[j + 1]);/* 从小到大 */
    				else if(style == false && L->elem[j] < L->elem[j + 1]) 
    					LIST_SWAP(L->elem[j],L->elem[j + 1]);/* 从大到小 */
    			}
    		}
    	}
    	return true;
    }
    

    如何按位置删除元素呢,请看下图:

    bool DeleteListElement(SeqList *L,int i)/* 删除元素 */
    {
    	if(IsListEmpty(L) == true || i < 0 || i > L->length)
    		return false;/* 表空,i的位置不合适都返回错误 */
    	else
    	{
    		for(int j = i;j < L->length;j++)
    		{
    			L->elem[j - 1] = L->elem[j];
    		}
    		L->length--;
    	}
    	return true;
    }
    

    最后,很好玩的是,顺序表可以合并哦~就好比女孩纸的手链串起来,感觉很整齐有木有:

    void MergeList(SeqList *L1,SeqList *L2,SeqList *L3)/* 合并顺序表 */
    {
    	int i = 0,j = 0,k = 0;
    	while (i < L1->length && j < L2->length)
    	{
    		if (L1->elem[i] <= L2->elem[j])
    		{
    			L3->elem[k++] = L1->elem[i++];
    		}
    		else
    		{
    			L3->elem[k++] = L2->elem[j++];
    		}
    	}
    	while (i < L1->length)
    	{
    		L3->elem[k++] = L1->elem[i++];
    	}
    	while (j < L2->length)
    	{
    		L3->elem[k++] = L2->elem[j++];
    	}
    	L3->length = L1->length + L2->length;
    }
    
    展开全文
  • 第一个知识点是顺序表,就是封装对一个数组操作,排序什么的等到后边复习到了再来补充,现在只有增删改查 因为之前都用java写各种项目作业什么的,所以C++语法忘得差不多,正在慢慢捡回来,正好趁这次机会...

    因为要考研,所以开始复习数据结构,每看完一个知识点,就用C++实现一下,以便加深印象

    第一个知识点是顺序表,就是封装对一个数组的操作,排序什么的等到后边复习到了再来补充,现在只有增删改查

    因为之前都是用java写各种项目作业什么的,所以C++语法忘得差不多的,正在慢慢捡回来,正好趁这次机会重新看了一下模板类,就用模板类实现了




    //SequenceTable.h

    #pragma once
    #include<iostream>
    using namespace std;
    //顺序表
    
    template <class T> class SequenceTable {
    private:
    	T *array;
    	int length;
    	int maxLength;
    public:
    	SequenceTable();							//默认构造函数
    	SequenceTable(int maxlength);				//带最大长度参数的构造函数
    	bool deleteByIndex(int index);				//通过下标删除元素
    	bool addByIndex(T t, int index);			//通过下标增加元素
    	bool add(T t);								//在表尾增加元素
    	T getByIndex(int index);					//通过下标得到元素
    	int getLength();							//得到当前表的长度
    	int getMaxLength();							//得到当前表的最大长度
    	void showAll();								//显示所有元素
    	bool replaceByIndex(T t, int index);		//通过下表替换元素
    };

    //SequenceTable.cpp

    #include"SequenceTable.h"
    
    template <class T> SequenceTable<T>::SequenceTable() {
    
    }
    
    template <class T> SequenceTable<T>::SequenceTable(int maxlength) {
    	array = new T[maxlength];
    	this->length = 0;
    	this->maxLength = maxlength;
    }
    
    template <class T> bool SequenceTable<T>::deleteByIndex(int index) {
    	if (index<0 || index>length - 1) {
    		return false;
    	}
    	for (int i = index + 1; i < length; i++) {
    		array[i - 1] = array[i];
    	}
    	length--;
    	return true;
    }
    
    template <class T> bool SequenceTable<T>::addByIndex(T t, int index) {
    	if (index<0 || index>length) {
    		return false;
    	}
    	length++;
    	for (int i = length - 1; i > index; i--) {
    		array[i] = array[i - 1];
    	}
    	array[index] = t;
    	return true;
    }
    
    template <class T> bool SequenceTable<T>::add(T t) {
    	array[length] = t;
    	length++;
    	return true;
    }
    
    template <class T> T SequenceTable<T>::getByIndex(int index) {
    	return array[index];
    }
    
    template <class T> int SequenceTable<T>::getLength() {
    	return length;
    }
    
    template <class T> int SequenceTable<T>::getMaxLength() {
    	return maxLength;
    }
    
    template <class T> void SequenceTable<T>::showAll() {
    	for (int i = 0; i < length; i++) {
    		cout << array[i] << "\t";
    	}
    	cout << endl;
    }
    
    template <class T> bool SequenceTable<T>::replaceByIndex(T t, int index) {
    	if (index<0 || index>=length) {
    		return false;
    	}
    	array[index] = t;
    	return true;
    }
    


    测试主函数

    (之前使用的是include的头文件,但是一直报错未定义,上网查了一下,模板类好像不是很支持分开文件写定义和实现,include源cpp文件就好了)

    #include<iostream>
    #include"SequenceTable.cpp"
    using namespace std;
    
    void main() {
    	SequenceTable<int> st(10);
    	st.add(1);
    	st.add(2);
    	st.add(3);
    	st.add(4);
    	st.showAll();
    	st.addByIndex(5, 3);
    	st.showAll();
    	st.deleteByIndex(0);
    	st.showAll();
    
    }




    展开全文
  • 数据结构--顺序

    2021-04-05 10:34:10
    顺序是数据结构中, 耿广义概念 数组 Java 语法中, 更具体概念 数组实现顺序一种典型方式 Java 实现顺序时候, 有一个专门类 ArrayList (针对普通数组进行封装) List: 线性表 ArrayList: 顺序...

    1. 什么是顺序表?

    顺序表是数据结构中, 耿广义的概念
    数组是 Java 语法中, 更具体的概念
    数组是实现顺序表的一种典型方式

    Java 实现顺序表的时候, 有一个专门的类 ArrayList (针对普通的数组进行封装)
    在这里插入图片描述

    List: 线性表
    ArrayList: 顺序表
    Collection: 元素集合

    一个线性表要提供的典型操作(增删改查), 就可以直接参考 List 接口里面的方法

    2. Java 中的 List 和 ArrayList 类

    方法 解释
    boolean add(元素类型 e) 将 e 尾插到线性表中
    void add(int index, 元素类型 e); e 插入到线性表的 index 位置处
    元素类型 remove(int index); 删除 index 位置的元素,并返回该元素;
    boolean remove(元素类型 e); 删除从前往后遍历时,遇到的第一个相等的(equals)元素
    元素类型 get(int index); 返回 index 位置的元素
    元素类型 set(int index, 元素类型 e); 用新的元素 e 替换 index 位置的元素,并返回 index 位置的原来的元素
    boolean contains(元素类型 e); 判断与元素 e 相等(equals)的元素是否存在于线性表中
    int indexOf(元素类型 e); 从前往后遍历的方式,找到第一个与元素 e 相等(equals)的元素的下标
    int lastIndexOf(元素类型 e); 从后往前遍历的方式,找到第一个与元素 e 相等(equals)的元素的下标
    void clear(); 清空线性表
    int size(); 返回线性表中已有元素的个数
    boolean isEmpty(); 返回线性表是不是一个空的容器
    Iterator iterator();
    void sort(Comparator 比较器);
    List subList(int fromIndex, int toIndex);

    3. 迭代器(Iterator)

    每种容器(Collection)都是具备迭代能力(Iterable)的。所以,每种容器都自带一个方法,返回一个合适的迭代器(Iterator)以对容器进行无视实现差别的迭代。

    ArrayList<String> list = new ArrayList<>();
    list.add("你好");
    list.add("中国");
    
    Iterator<String> it = list.iterator();
    // 只要还有下一个元素,循环就继续
    while (it.hasNext()) {
        // 获取下一个元素,并让迭代器走到之后的位置上
        String e = it.next();
        
        // 可以在合适的条件下,对当前迭代器正处于的元素进行删除
        it.remove();
    }
    

    4. 实现 ArrayList

    import java.util.Arrays;
    
    public class MyArrayList {
        // 属性
        // 数组为空数组
        private String[] date = null;
        // 数组长度为 0
        private int size = 0;
        // 数组最大容量为 100,超出容量就需要扩容
        private int capacity = 100;
    
        public MyArrayList() {
            date = new String[capacity];
        }
    
        public void realloc() {
            // 准备一个更大容器
            capacity = 2 * capacity;
            String[] newDate = new String[capacity];
            // 将 date 中数据拷贝到 newDate 中
            for (int i = 0; i < size; i++){
                newDate[i] = date[i];
            }
            date = newDate;
        }
    
        // 1.插入操作
        // 尾插
        public void add(String e) {
            // 如果 size >= capacity 则需要扩容
            if (size >= capacity) {
                realloc();
            }
            date[size] = e;
            size++;
        }
        // 任意位置插入
        public void add(int index, String e) {
            // 先判断是否小需要扩容
            if (size >= capacity) {
                realloc();
            }
            // 找到插入元素位置,将该位置和以后元素依次向后移位
            for (int i = size - 1; i >= index; i--) {
                date[i + 1] = date[i];
            }
            date[index] = e;
            size++;
        }
    
        // 2.删除元素
        // 按照下标元素删除,这个方法返回删除的元素
        public String remove(int index) {
            // 注意先判断边界条件
            if (index < 0 || index >= size) {
                return null;
            }
             // 找到下标元素返回,将之后元素依次向前移
            String ret = date[index];
            for (int i = index - 1; i < size; i++) {
                date[i] = date[i + 1];
            }
            // 更新 size
            size--;
            return ret;
        }
    
        // 指定元素删除,返回是否删除成功
        public boolean remove(String e) {
            // 遍历寻找指定元素
            int index = 0;
            for ( ; index < size; index++) {
                if (date[index].equals(e)) {
                    break;
                }
            }
            // 若元素是最后一个,直接 -- 即可
            if (index == size) {
                size--;
            }
            // 将元素覆盖
            for (; index < size; index++) {
                date[index] = date[index + 1];
            }
            size--;
            return true;
        }
    
        // 3.获取指定位置元素
        public String get(int index) {
            if (index < 0 || index >= size) {
                // 可以返回 null 也可以抛出一个异常
                // return null;
                throw new MyArrayListIndexOutOfRangeException("下标越界了! index:" + index);
            }
            return date[index];
        }
    
        // 4.修改指定位置元素
        public void set(int index, String e) {
            if (index >= size || index < 0) {
                // return null;
                throw new MyArrayListIndexOutOfRangeException("下标越界了! + index");
            }
            date[index] = e;
        }
    
        // 5.判断元素是否存在
        public boolean contains(String e) {
            for (int i = 0; i < size; i++) {
                if (date[i].equals(e)){
                    return true;
                }
            }
            return false;
        }
    
        // 6.查找元素位置
        public int indexOf(String e) {
            for (int i = 0; i < size; i++) {
                if (date[i].equals(e)) {
                    return i;
                }
            }
            // 未找到元素,返回 -1
            return -1;
        }
    
        // 7.查找指定元素(从后往前遍历)
        public int lastIndexOf(String e) {
            for (int i = size - 1; i >= 0; i--) {
                if (date[i].equals(e)) {
                    return i;
                }
            }
            return -1;
        }
    
        // 清空线性表
        public void clear() {
            size = 0;
        }
    
        // 返回线性表已有元素个数
        public int size() {
            return size;
        }
    
        // 返回线性表是否为空
        public boolean isEmpty() {
            // 判断线性表长度
            // 长度为 0 返回 true
            return size == 0;
        }
    
    
    
    
    
    
    
    
        @Override
        public String toString() {
            // 直接使用,缺点会输出 null
    //        return Arrays.toString(date);
            // 自己重写方法
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("[");
            for (int i = 0; i < size; i++) {
                stringBuilder.append(date[i]);
                if (i < size - 1) {
                    stringBuilder.append(",");
                }
            }
            stringBuilder.append("]");
            return stringBuilder.toString();
        }
    
        public static void main(String[] args) {
            MyArrayList date = new MyArrayList();
            date.add("c");
            date.add(1,"c++");
            date.add("java");
    //        date.remove("c++");
    //        date.remove(1);
            System.out.println(date.get(2));
            date.set(2,"c+");
            System.out.println(date.contains("java"));
            System.out.println(date.indexOf("c+"));
            System.out.println(date.lastIndexOf("c"));
            System.out.println(date.size);
            System.out.println(date);
            date.clear();
            System.out.println(date.isEmpty());
    
        }
    
    
        class MyArrayListIndexOutOfRangeException extends RuntimeException {
            public MyArrayListIndexOutOfRangeException(String message) {
                super(message);
            }
        }
    }
    
    展开全文
  • 首先,我们要知道什么是函数,什么是指针。 函数:emm,通俗来讲就是把一系列操作封装好,然后有入口(参数),可以有出口(返回值)。 指针:在C语言中,直接这么理解可以省很多事情:指针就是地址,地址就是指针...

    顺序表

    重点

    函数指针与指针函数

    关于函数指针与指针函数的概念,其实很好理解。
    首先,我们要知道什么是函数,什么是指针。

    • 函数:emm,通俗来讲就是把一系列操作封装好,然后有入口(参数),可以有出口(返回值)。
    • 指针:在C语言中,直接这么理解可以省很多事情:指针就是地址,地址就是指针。稍微解释下的话,就是指针变量用于存放内存地址。
      好了,再拓展下函数与指针的知识:
    • 函数拓展:在面向对象语言中,有类、对象、方法等概念。类中的函数就称为方法。比如说人是一个类,那么特朗普就是个对象,特朗普吃饭就是一个方法。特朗普的身高体重就是成员变量等。
    • 指针拓展:整形指针是存放整形变量的内存地址的变量,字符指针是存放字符变量的内存的地址。多级指针是存放指针变量的内存的地址。

    现在来正式理解函数指针与指针函数:

    • 函数指针:存放函数的内存的地址,类比面向对象语言中的方法与成员变量,当我们认为函数与整形变量具有同等的地位时(都占用内存),我们可以为函数定义一个指针。

      • 注意:整形变量的指针 定义方法int * p是因为描述整形变量只有一个int,而描述函数有参数和返回值,所以函数指针的写法是:int (*fun)(int a,int b)
    • 指针函数:返回值是指针变量的函数,这个就很简单了。
      写法int* fun(int a,int b)

    小练习:
    int* (*fun)(int *a)是啥:
    答案: 这是一个参数为整形指针,返回值为整形指针的指针函数。

    插入函数的实现

    我们线性顺序表的插入方案效率最高只有O(n)。下面来解释下这个思路,我太懒了,所以就不写代码了。
    对于顺序表,最大的特点是连续,所以我们没有办法拆开一块连续的内存放入一个数据。那么只能退而求其次:
    一个顺序表模拟成十个人排队买饭
    这时候第五个人我发现我认识。
    我就很臭不要脸的站在了第五个人的前面
    然后我后面的人都往后退了一个位置
    我这个数据就被插入到顺序表了

    删除函数的实现

    接着上面的说:
    有个壮汉看我插队很不爽
    一脚给我踹出了队伍。
    然后,我后面的每个人都向前移动了一个位置。

    清空与销毁

    在了解这个清空与销毁之前,先了解一个概念:内存泄露
    我们模拟一个场景:
    我去拿快递,很兴奋,拿到快递之后就把快递盒子扔掉了。我就走了,然后有个喜欢我的姑娘看到了这一幕,偷偷的捡起了盒子,拍下了我快递单,然后我就有女朋友了,就再也不能敲代码了,是不是很恐怖?
    在这个故事中,我拿着快递盒子的手就是一个指针,快递盒子就是内存。这个指针指向内存的时候,没问题。当我不指向内存了,这内存就没用了,然后会被有心人利用,对程序造成危险。这个内存泄露在c、c++中是个很严重的问题,因为c、c++都要开发者自己把快递盒上的快递单撕个粉碎,但是java就有良好的内存管理机制,一旦快递盒被扔出去,就自动被粉碎。这个就说很多了。总之一句话,一个优秀的开发者,是不会有女朋友的(手动狗头)
    为什么要介绍内存泄露呢?
    其实就是我们清空与销毁的区别。
    清空函数中:我们只是把pr->length归零了,内存没有变化。(其实也可以变化,只不过会影响效率,我们不变化的原因只是没有必要。为啥没有必要呢?因为我们所有的操作都先判断了下length)
    销毁函数中:我们通过对elem指针执行free操作,释放掉了所有的内存。

    区别:清空之后,我们还需要对顺序表进行操作。所以内存不能释放,也没有必要释放。销毁之后,我们不要这个顺序表了,所以我们把内存归还给系统。
    换句话说:

    • 清空==我把快递盒放下,又拿起来了。快递盒还是我的。
    • 销毁==我把快递盒扔了。

    引用

    老师在上课的时候说的不太清楚,或者怕我弄混了吧,我来形象的记录下,反正闲的没事干。
    引用这个在c语言中是没有的, 因为这个是c++的语法。注意C语言没有引用
    下面来比较下:
    void fun(int a)
    如果程序调用这个函数,a作为形参只是接收到了实参的一个副本,也就是说,改变实参改变不了形参
    void fun(int * a)
    参数为指针,可以通过函数修改实参的值,只不过需要用*a来操作
    void fun(int &a)
    可以用a = 10;的方法修改实参的值,也就是说,可以达到指针的效果,并且比指针用起来更舒服

    剩下的就是干货,直接上代码

    说明

    为了克制自己不自觉的使用c++简单的语法和函数,下面的代码均用纯c实现。

    操作

    int InitList(SortList * pr); //初始化 
    
    int InsertList(SortList* pr,int i, Student e); //插入 
    
    int DelList(SortList* pr,int i,Student *temp);//删除 
    
    int PrintList(SortList * pr);//打印 
    
    void ClearList(SortList * pr) ;//清空顺序表
    
    void DestoryList(SortList * pr);//销毁顺序表 
    
    int LenList(SortList * pr);//获取表长
    
    int isEmptyList(SortList * pr);//是否为空表 
    
    int getElemList(SortList * pr,int i,Student * data);//按下标找数据 
    
    int compare(Student *a,Student *b);
    int LocateElem(SortList* pr,Student * e,int (*compare)(Student *a,Student*b));// 每个元素与e进行函数操作 
    
    int PreElem(SortList * pr,Student* e,Student * value);//求某元素的前驱元素
    
    int NextElem(SortList * pr,Student* e,Student * value);//求某元素的后继元素 
    
    int solve(Student *a);
    int ListSolve(SortList *pr,int (*solve)(Student *a));//元素分别执行函数 
    
    

    代码实现

    /**
    	project: 线性表的顺序存储实现
    	author: mmciel
    	time:2019年3月6日23:54:54 
    	version:1.0 
    	update:
    		2019年3月6日23:56:23
    			实现顺序表的初始化
    		2019年3月7日09:50:02
    			实现顺序表的插入、遍历、删除
    		2019年3月7日01:02:06
    			实现顺序表关于函数指针等的操作 
    		2019年3月8日18:21:00
    			实现顺序表剩下的操作 
    			
    		2019年3月8日20:00:43
    			完成调试与修改 
    */ 
    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <string.h>
    
    #define LIST_INIT_SIZE 100 //初始化顺序表的大小 
    #define LIST_ADD 10 //每次顺序表内存扩展的大小 
    
    //定义一个学生类型,用于复杂一点的测试 
    typedef struct{
    	int number;
    	char name[20];
    	int score;
    }Student;
    //定义连续存储的线性表 
    typedef struct{
    	Student* elem;//学生类型的指针 
    	int length;//表中的数据长度 
    	int listsize; //表的当前内存容量 
    }SortList;
    
    int InitList(SortList * pr); //初始化 
    
    int InsertList(SortList* pr,int i, Student e); //插入 
    
    int DelList(SortList* pr,int i,Student *temp);//删除 
    
    int PrintList(SortList * pr);//打印 
    
    void ClearList(SortList * pr) ;//清空顺序表
    
    void DestoryList(SortList * pr);//销毁顺序表 
    
    int LenList(SortList * pr);//获取表长
    
    int isEmptyList(SortList * pr);//是否为空表 
    
    int getElemList(SortList * pr,int i,Student * data);//按下标找数据 
    
    int compare(Student *a,Student *b);
    int LocateElem(SortList* pr,Student * e,int (*compare)(Student *a,Student*b));// 每个元素与e进行函数操作 
    
    int PreElem(SortList * pr,Student* e,Student * value);//求某元素的前驱元素
    
    int NextElem(SortList * pr,Student* e,Student * value);//求某元素的后继元素 
    
    int solve(Student *a);
    int ListSolve(SortList *pr,int (*solve)(Student *a));//元素分别执行函数 
    
    void ge(){
    	printf("===============================================\n");
    } 
    int main()
    {
    	//初始化几个数据
    	Student studata[] = {
    		{1000,"xiao_zhang",99},
    		{1001,"xiao_zhao",80},
    		{1002,"xiao_liu",70}
    	};
    	Student temp_data1 = {1004,"xiao_he",100};
    	Student temp_data2 = {1002,"xiao_liu",70};
    	Student stu;
    	//定义一个顺序表 
    	SortList data; 
    	SortList * pr = &data;
    	//初始化
    	if(InitList(pr)){
    		printf("init success!\n");
    	} 
    	else{
    		printf("init error!\n");
    	}
    	ge();
    	//插入 
    	int ia = InsertList(pr,1,studata[0]);
    	int ib = InsertList(pr,1,studata[1]);
    	int ic = InsertList(pr,2,studata[2]);
    	if(ia == ib == ic){
    		printf("insert success\n"); 
    	} 
    	else{
    		printf("insert error\n"); 
    	} 
    	PrintList(pr);
    	ge();
    	//删除
    	int da = DelList(pr,1,&stu);
    	PrintList(pr); 
    	ge();
    	//表长
    	printf("length = %d\n",LenList(pr));
    	ge();
    	
    	//按照第几个找数据 
    	getElemList(pr,1,&stu);
    	printf("%-10d%-10s%-10d\n",stu.number,stu.name,stu.score); 
    	ge();
    	//求前驱和后继
    	
    	ib = InsertList(pr,1,studata[1]);//先凑够三个
    	PrintList(pr);
    	PreElem(pr,&studata[2],&stu);
    	printf("前驱:%-10d%-10s%-10d\n",stu.number,stu.name,stu.score); 
    	NextElem(pr,&studata[2],&stu);
    	printf("后继:%-10d%-10s%-10d\n",stu.number,stu.name,stu.score); 
    	ge();
    	//与指定元素进行函数操作
    	printf("%d\n",LocateElem(pr,&studata[2],&compare));
    	ge();
    	// 所有元素执行指定元素
    	ListSolve(pr,&solve);
    	ge();
    
    	//清空与判空
    	ClearList(pr);
    	if(isEmptyList(pr)){
    		printf("empty list\n");
    	} 
    	ge();
    	//销毁
    	DestoryList(pr);
    	if(!pr->elem){
    		printf("destory success\n");
    	}
    	else{
    		printf("destory error\n");
    	}
    	 
    	return 0;
    }
    //初始化指定长度的顺序表 
    int InitList(SortList * pr){
    	/*
    		采用动态内存分配的方案
    		pr: 顺序表指针,此时指针并没有大量的内存可以使用 
    	*/
    	(*pr).elem = (Student*)malloc(LIST_INIT_SIZE*sizeof(Student));
    	if(!(*pr).elem) 
    		exit(-1);
    	(*pr).length = 0;
    	(*pr).listsize = LIST_INIT_SIZE;
    	return 1; 
    }
    //插入元素
    int InsertList(SortList* pr,int i, Student e)
    {
    	/*
    		在线性表pr中的第i个位置之前插入一个元素e
    		实现思路:先后移,然后把e存入指定位置
    		pr:顺序表 
    		i:需要插入的位置 
    		e:	需要插入的数据 
    	*/	
    	//检查i的合法性
    	if(i<1 || i>(*pr).length+1)
    		return 0;
    	//增加空间分配 
    	if((*pr).length >= (*pr).listsize){ 
    		Student* newbase = (Student*)realloc( (*pr).elem, ((*pr).listsize+LIST_ADD)*sizeof(Student) );
    		if(!newbase){
    			exit(-1);
    		} 
    		(*pr).elem = newbase;
    		(*pr).listsize += LIST_ADD;
    		//length不用更新 ,因为还没有添加 
    	} 
    	//取得待插入的地址 
    	Student * temp = &((*pr).elem[i-1]);
    	//元素后移
    	//利用指针移动i后面的元素腾出位置 
    	Student * p;
    	for(p = & ( (*pr).elem[(*pr).length-1] ) ;p >= temp; --p){
    		*(p+1) = *p;
    	} 
    	*temp = e;
    	(*pr).length++;
    	 return 1;
    } 
    
    //删除元素 
    int DelList(SortList* pr,int i,Student *temp)
    {
    	/*
    		 在顺序表pr中,删除第i位置的元素,删除元素存入temp备份 
    		 pr:顺序表
    		i:待删除的位置
    		temp:删除后的数据备份 
    	*/
    	//判断i值合法性
    	if(i>pr->length || i<1){
    		return 0;
    	} 
    	//获得被删除元素的地址
    	Student * del = (pr->elem)+(i-1);
    	
    	*temp = *del;//备份
    	
    	Student * wei = (pr->elem)+(pr->length-1);//获取尾部地址
    	
    	for(del++;del<=wei;del++){
    		*(del-1) = *del;
    	} 
    	(*pr).length--;
    	return 1;
    	
    }
    //清空 
    void ClearList(SortList * pr){
    	pr->length = 0;
    }
    //销毁 
    void DestoryList(SortList * pr){
    	free(pr->elem) ;
    	pr->elem = NULL;
    	pr->length = 0;
    	pr->listsize = 0;
    } 
    //遍历元素
    int PrintList(SortList * pr){
    	/*
    	 遍历pr 打印属性 
    	 
    	*/
    	int i=0;
    	int len = (*pr).length;
    	Student * p = pr->elem;//不能直接移动pr->elem 会导致真正的elem发生改变 
    	printf("%-10s%-10s%-10s\n","number","name","score");
    	for(int i=0;i<len;i++){
    		
    		printf("%-10d%-10s%-10d\n",p->number,p->name,p->score);
    		p++;//elem前进 
    	}
    	return 1;
    }
    //获取表长
    int LenList(SortList * pr){
    	return pr->length;
    } 
    //是否为空表 
    int isEmptyList(SortList * pr){
    	if(pr->length == 0){
    		return 1;
    	}
    	else{
    		return 0;
    	}
    } 
    
    int getElemList(SortList * pr,int i,Student * data){
    	/*
    		在pr顺序表中 提取下标为index 的数据到data 
    		
    	*/
    	//检查i的合法性
    	if(i<1 || i>pr->length){
    		return 0;
    	} 
    	else{
    		*data = *((pr->elem)+(i-1)); 
    		return 1;
    	}
    }
    int compare(Student *a,Student *b){
    	if(!strcmp(a->name,b->name) && a->number==b->number && a->score == b->score){
    		return 1;
    	}
    	else{
    		return 0;
    	}
    } 
    // 查找与e相同的元素的位置(不是下标) 
    int LocateElem(SortList* pr,Student * e,int (*compare)(Student *a,Student*b)){
    	int i=1;//代表的是长度 所以不是想象中的i=0; 
    	Student * p=pr->elem;
    	while (i<=pr->length && !(*compare)(p++,e)) 
     		++i;
    	if (i<=pr->length)
            return i;
    	else  
            return 0;
    } 
    //求某元素的前驱元素
    int PreElem(SortList * pr,Student* e,Student * value){
    	int i = 1;
    	Student *p = pr->elem;
    	for(;i<pr->length;i++,p++){
    		if(p->number == e->number && p->score == e->score && !(strcmp(p->name,e->name)) ){
    			*value = *(p-1);
    			return 1;
    		}
    	} 
    	return 0;
    }
    //求某元素的后继元素 
    int NextElem(SortList * pr,Student* e,Student * value){
    	int i = 0;
    	Student *p = pr->elem;
    	for(;i<pr->length-1;i++,p++){
    		if(p->number == e->number && p->score == e->score && !(strcmp(p->name,e->name)) ){
    			*value = *(p+1);
    			return 1;
    		}
    	} 
    	return 0;
    } 
    int solve(Student *a){
    	Student temp = *a;
    	printf("%-10d%-10s%-10d\n",temp.number,temp.name,temp.score);
    }
    int ListSolve(SortList *pr,int (*solve)(Student *a)){
    	Student * e = pr->elem;
    	int i=0;
    	for(;i<pr->length;i++){
    		
    		if((*solve)(e)){
    			e++;
    		}
    		else{
    			return 0;
    		}
    	}
    	return 1;
    }
    
    
    
    展开全文
  • 现在看一下,对于整型数据int = 1,2,3,4,5(基本数据类型),对于这部分数据该...首要一点是要知道数据存贮本质是什么? 内存 计算机内存是存储数据并直接与CPU打交道。既然是内存,那就是存储单元了,即组...
  • 链表(Linked List) 一种常见基础数据结构,一只种类线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点位置信息(即地址)。 链表结构可以充分利用计算机内存空间,实现...
  • 链表(Linked List)一种常见基础数据结构,一只种类线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点位置信息(即地址)。 那么什么是单链表呢? 单向链表也叫...
  • 目录封装什么封装封装方法封装例子封装特性面向对象的封装有三种形式:继承什么是继承为什么要继承如何用继承单继承多继承新式类、经典类继承与抽象派生类组合属性查找顺序重写子类中访问父类内容子类初始化...
  • 随笔感悟 — 函数封装

    千次阅读 2017-10-17 23:34:55
    (例子:数据结构顺序表,其添加删除肯定属于基本逻辑操作,但这顺序表的长度到底有什么封装的必要,顺序表诶,四舍五入等于数组,求个长度还封装,哇,一句代码的事情诶,有没有搞错(我就举一个小例子 -我愿意...
  • 如果上层封包被切割处理,所有帧片段都会具有相同的顺序编号。如果重传帧,则顺序编号不会有任何改变。帧片段之间的差异在于 fragment number (片段编号)。第一个片段的编号为 0 。其后每个片段依序累加 1 。重...
  • 顺序

    2020-05-30 16:18:41
    再有就是在栈里的存数据了,不能查看数据的(就不能说什么遍历数据,显示出来了),只能返回其大小,原理就是同可比克,它是封装的,外界只能查看栈顶的数据! 栈的主要操作有: 查看栈顶数据(top) 进栈(push) ...
  • C语言实现顺序

    2016-04-07 21:18:28
    所以顺序表一种在学C的过程中必须掌握的结构,通过学习整理,下面来实现一下: 首先,先要想好用什么实现,一般实现最基本的顺序表的话直接用数组实现,我们在这用一个结构体来封装这个顺序表(封装这一概念在...
  • 封装:封装的意义在于明确表示出允许外部使用的所有成员函数和数据项。内部细节对外部调用透明,外部调用无需修改或者关心内部实现。 如:javabean的属性私有,提供get、set方法对外访问,因为属性的赋值或者获取...
  • 顺序表分为动态顺序表以及动态的顺序表,静态的顺序表一般很少使用,因为其大小一旦固定不能再进行改变。   顺序表在开发中十分经常使用,因为其方便简单,并且易于操作。数组就是顺序表的一种,因为其在逻辑结构...
  • 什么是面向对象 面向过程更注重事情的每一个步骤及顺序,面向对象更注重事情有哪些参与者(对象...封装的意义,在于明确标识出允许外部使用的所有成员函数和数据项 内部细节对外部调用不透明,外部调用无需修改或者关心
  • 从一个数据集合中按照一定的顺序,不断取出数据的过程 迭代和遍历的区别? 迭代强调的依次取数据,并不保证取多少,也不保证把所有的数据取完 遍历强调的要把整个数据依次全部取出 例:在生活中,我们经常听到一...
  •  这种形式程序段我们将其称之为代码块,所谓代码块就是用大括号({})将多行代码封装在一起,形成一个独立的数据体,用于实现特定算法。一般来说代码块不能单独运行,它必须要有运行主体。在Java中代码块主要...
  • 什么是消息队列

    2020-12-21 18:39:12
    队列中存放的数据,将自字符串封装的消息对象 1.2消息队列的作用 ❤解耦 代码,或者系统通信都可能存在强耦合的关系,可以通过消息队列第三方技术处理强耦合,解耦 ❤消峰(消除并发峰值) 请求到达系统的方法上限,超过...
  • 1、什么是数据结构? 数据结构计算机存储、组织数据的方式 2、线性表 线性表具有 n 个相同类型元素有限序列( n ≥ 0 ) 常见线性表有 ①、数组 ②、链表 ③、栈 ④、队列 ⑤、哈希表(散列表) 3...
  • ssd是什么硬盘

    2021-06-01 10:28:42
    SSD 控制器架构配置经过优化,可为顺序和随机数据请求提供高读写性能。SSD 有时被称为闪存驱动器或固态磁盘。 SSD 与硬盘驱动器(HDD)不同,SSD 没有移动部件可以断开或旋转或旋转。传统硬盘驱动器由一个旋转...
  • 栈与队列栈栈定义栈实现队列队列定义队列实现队列扩展—双端队列双端队列实现 ...a1到an数据顺序表存储,顺序特点就是连续存放一组数据,只要在栈中封装顺序表时,保证使用时只能从一端...
  • SSD固态硬盘是什么

    2021-06-01 10:27:31
    SSD 控制器架构配置经过优化,可为顺序和随机数据请求提供高读写性能。SSD 有时被称为闪存驱动器或固态磁盘。 SSD 与硬盘驱动器(HDD)不同,SSD 没有移动部件可以断开或旋转或旋转。传统硬盘驱动器由一个旋转...
  • 1)迭代的定义:从一个数据集合中按照一定的顺序,不断取出数据的过程称为迭代 2)迭代和遍历的区别 迭代:迭代强调的依次取数据的过程,并不保证取多少,也不保证把所有的数据都取完 遍历:遍历强调的要把...
  • 可靠:通信的双方能保证发送的数据一定能够按正确的大小,正确的顺序原样的到达另一方,如果数据不能到达或者有其他的问题,发送方一定可以及时的得到通知 连接:通讯双方存在虚电路连接 可靠:指发送方的上层协议/...
  • 数据结构意味着接口或封装:一个数据结构可被视为两个函数之间接口,或者数据类型联合组成存储内容访问方法封装 数组最简单内存数据结构,下面常见的数据结构: 数组(Array) 栈(Stack) 队列...
  • 类型萃取是一种常用的编程技巧,其目的是实现不同类型数据面对同一函数实现不同的操作,它与类封装的区别是,我们并不用知道我 们所调用的对象是什么类型,类型萃取是编译后知道类型,先实现,而类的封装则是先定义...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 409
精华内容 163
关键字:

数据封装的顺序是什么