
数据结构c语言版 使用线性表的顺序储存结构定义(静态)实现线性表的初
直接上源码吧。
\\\/*线性表功能的实现*\\\/#include
); scanf(%d,&input_number); printf(\\\ ); deleteList(&L, input_number, &input_value); listTraverse(L); break; case 8: res = getListLength(L); printf(线性表的长度是:%d,res); break; case 9: res = listEmpty(L); if(res){ printf(线性表的是空的); }else{ printf(线性表的是不是空的); } break; } } return OK;} 线性表的特征是:1. 元素之间是有序的,如果元素存在多个,则第一个元素无前驱,最后一个无后继,其它元素都有且只有一个前驱和后继.2. 元素个数是有限的. 当n=0是,称为空表线性表实现方式有两种,分别是顺序存储结构和链式存储结构,它们之间各有优缺点 . 根据需求的不同进行选择不同的存储结构.线性表存储结构的优缺点优点:1. 无须为表中元素之前的逻辑关系而增加额外的存储空间2. 可以快速的存取表中的任一位置的元素缺点:1. 插入和删除操作需要移动大量元素2. 当线性表长度变化较大时,难以确定存储空间的容量.3. 造成存储空间的”碎片”.
线性表和顺序表的区别
这个问题很奇怪啊。
约瑟夫环问题最直接的解决方式就是个循环链表,不停的删除链表中的元素。
如果觉得删除操作太麻烦,用个数组,然后标记数组里面被删除的元素也是一种选择。
为什么还要用其他的数据结构
线性表就是一个数组
我们也只用数组来描述线性表
对不对
从定义上来看,线性表和数组都是数据元素的有序集,两者的区别在哪里
首先,数组有维度(比如三维数组)的概念而线性表没有,虽然我们可以通过设计一些含指针的数据结构的线性表,使之可以模仿多维数组的操作,但这已经超出了常规的线性表的概念。
其次,数组和线性表上可进行的操作不一样。
比如,一般我们不在数组上进行数据插入和删除的操作,同样,我们也无法直接通过数据序列来访问线性表中的数据单元(比如表中第i个元素)。
但是,对于初学者而言,为了方便对二者概念的消化,我们可以将一维的数组(注意是一维的)等同于线性表来理解,因为他们多数的性质都是类似的。
但是我们不能说,线性表就是一个数组,这是不对的。
对该问题的回答中有人说“线性表是先存入的后出,后存入的先取出”,显然是混淆了线性表和堆栈的概念,在此不再多说,请查阅相关资料。
静态分配和动态分配内存的区别
内存的静态分配和动态分配的区别主要是两个: 一是时间不同。
静态分配发生在程序编译和连接的时候。
动态分配则发生在程序调入和执行的时候。
二是空间不同。
堆都是动态分配的,没有静态分配的堆。
栈有2种分配方式:静态分配和动态分配。
静态分配是编译器完成的,比如局部变量的分配。
动态分配由函数malloc进行分配。
不过栈的动态分配和堆不同,他的动态分配是由编译器进行释放,无需我们手工实现。
对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。
动态数据区一般就是“堆栈”。
“栈(stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。
进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。
一个堆栈可以通过“基地址”和“栈顶”地址来描述。
全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。
程序通过堆栈的基地址和偏移量来访问本地变量。
一般,用static修饰的变量,全局变量位于静态数据区。
函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。
所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。
动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。
例如我们定义一个float型数组:float score[100]; 但是,在使用数组的时候,总有一个问题困扰着我们:数组应该有多大
在很多的情况下,你并不能确定要使用多大的数组,比如上例,你可能并不知道我们要定义的这个数组到底有多大,那么你就要把数组定义得足够大。
这样,你的程序在运行时就申请了固定大小的你认为足够大的内存空间。
即使你知道你想利用的空间大小,但是如果因为某种特殊原因空间利用的大小有增加或者减少,你又必须重新去修改程序,扩大数组的存储范围。
这种分配固定大小的内存分配方法称之为静态内存分配。
但是这种内存分配的方法存在比较严重的缺陷,特别是处理某些问题时:在大多数情况下会浪费大量的内存空间,在少数情况下,当你定义的数组不够大时,可能引起下标越界错误,甚至导致严重后果。
我们用动态内存分配就可以解决上面的问题. 所谓动态内存分配就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。
动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。
从以上动、静态内存分配比较可以知道动态内存分配相对于景泰内存分配的特点: 1、不需要预先分配存储空间; 2、分配的空间可以根据程序的需要扩大或缩小。
要实现根据程序的需要动态分配存储空间,就必须用到malloc函数.malloc函数的原型为:void *malloc (unsigned int size) 其作用是在内存的动态存储区中分配一个长度为size的连续空间。
其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。
还有一点必须注意的是,当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针。
所以在调用该函数时应该检测返回值是否为NULL并执行相应的操作。
静态内存是在程序一开始运行就会分配内存,直到程序结束了,内存才被释放。
动态内存是在程序调用在程序中定义的函数时才被分配,函数调用结束了,动态内存就释放。
static int a;这是定义了一个静态的变量int a;这是定义了一个动态的变量;静态内存可以用于求阶层。
例如:jiechen(int i){static int a=1;for(;a<=i,a++)return a*i;}#includestdio.hmain(){int a,i;printf(enter number:)scanf(%d,&a);for(i=1;i<=a;i++)printf(i!=%d\\\ ,jiechen(i));}运行输入3结果为1
=1 2!=2 3!=3由malloc系统函数分配的内存就是从堆上分配内存。
从堆上分配的内存一定要自己释放。
用free释放,不然就是术语——“内存泄露”(或是“内存漏洞”)—— Memory Leak。
于是,系统的可分配内存会随malloc越来越少,直到系统崩溃。
还是来看看“栈内存”和“堆内存”的差别吧。
栈内存分配 ————— char* AllocStrFromStack() { char pstr[100]; return pstr; } 堆内存分配 ————— char* AllocStrFromHeap(int len) { char *pstr; if ( len <= 0 ) return NULL; return ( char* ) malloc( len ); }对于第一个函数,那块pstr的内存在函数返回时就被系统释放了。
于是所返回的char*什么也没有。
而对于第二个函数,是从堆上分配内存,所以哪怕是程序退出时,也不释放,所以第二个函数的返回的内存没有问题,可以被使用。
但一定要调用free释放,不然就是Memory Leak
在堆上分配内存很容易造成内存泄漏,这是C\\\/C++的最大的“克星”,如果你的程序要稳定,那么就不要出现Memory Leak。
所以,我还是要在这里千叮咛万嘱付,在使用malloc系统函数(包括calloc,realloc)时千万要小心。
记得有一个UNIX上的服务应用程序,大约有几百的C文件编译而成,运行测试良好,等使用时,每隔三个月系统就是down一次,搞得许多人焦头烂额,查不出问题所在。
只好,每隔两个月人工手动重启系统一次。
出现这种问题就是MemeryLeak在做怪了,在C\\\/C++中这种问题总是会发生,所以你一定要小心。
一个Rational的检测工作——Purify,可以帮你测试你的程序有没有内存泄漏。
我保证,做过许多C\\\/C++的工程的程序员,都会对malloc或是new有些感冒。
当你什么时候在使用malloc和new时,有一种轻度的紧张和惶恐的感觉时,你就具备了这方面的修养了。
对于malloc和free的操作有以下规则:1) 配对使用,有一个malloc,就应该有一个free。
(C++中对应为new和delete)2) 尽量在同一层上使用,不要像上面那种,malloc在函数中,而free在函数外。
最好在同一调用层上使用这两个函数。
3) malloc分配的内存一定要初始化。
free后的指针一定要设置为NULL。
注:虽然现在的操作系统(如:UNIX和Win2k\\\/NT)都有进程内存跟踪机制,也就是如果你有没有释放的内存,操作系统会帮你释放。
但操作系统依然不会释放你程序中所有产生了Memory Leak的内存,所以,最好还是你自己来做这个工作。
(有的时候不知不觉就出现Memory Leak了,而且在几百万行的代码中找无异于海底捞针,Rational有一个工具叫Purify,可能很好的帮你检查程序中的Memory Leak)第一个例子也讲得不清楚。
所谓系统释放,应该是指系统在自己的表里把这段内存标记为可以使用,以后可以被别的程序使用,所以第一个例子会造成程序能访问到已经释放的内存空间,是越界,会造成不可预测的情况。
系统一般不会自动去清除释放空间内的数据,而是由以后的程序来覆盖。
所以很多程序开头都会做MEMSET(...),就是为了防止这种垃圾数据的情况。
如果在程序运行中要改变内存块的大小,可以用RALLOC()函数,它能在原来地址上重新分配一块空间,不过是用的时候要小心,也是比较容易出问题
线性表的操作(C++)
#include



