您的位置:首页 > 理论基础 > 数据结构算法

数据结构分析之——顺序表

2012-04-22 20:19 190 查看
废话不多说,也没时间说。今年6月前着重数据结构。

详细看代码,方便。

代码个人敲的,若有错误,敬请指正。

#include<iostream>
#define MaxSize 10
#define Increasment 5
using namespace std;

typedef struct{        //动态顺序表结构
int *elem;
int length;
int ListSize;
}SqList;

void InitList(SqList *L);                        //初始化一个顺序表
void InsertList(SqList *L,int Pos,int elem);    //在顺序表L中的位置Pos插入元素elem
void Print(SqList *L);                          //打印顺序表L中的元素,全打印
void VirValue(SqList *L, int sPos, int ePos);   //把顺序表L中位置StartPos到EndPos位置的元素置0
void Delete(SqList *L,int Pos);                 //删除顺序表L中pos位置的元素

int main()
{
int iPos,iElem;
int Confirm;
SqList L;
/*postfix-expression . identifier
postfix-expression represents a value of struct or union type,
postfix-expression –> identifier
postfix-expression represents a pointer to a structure or union,
*/
InitList( &L );
cout << "Try to insert or delete an element?" << endl
<< "1 for insert an element" << endl
<< "2 for delete an element" << endl
<< "CTRL+D for quit " << endl;
while(  cin >> Confirm )                            //ctrl + d 结束输入,跳出整个while循环
{
switch(Confirm)
{
case 1: {
cout << "Input Position and Element" << endl;
cin >> iPos >> iElem;
InsertList(&L, iPos, iElem);
cout << "Sequence\tMEM_addr\t\tSize\t\tElement" << endl;
Print( &L );
}
break;
case 2: {
cout << "Input Position" << endl;
cin >> iPos;
Delete(&L,iPos);
cout << "Sequence\tMEM_addr\t\tSize\t\tElement" << endl;
Print( &L );
}
break;
default:
cout << "Non-existed options!" << endl;
break;
}
}
cout << "Cancel,Current Sequence is bellow" << endl;
cout << "Sequence\tMEM_addr\t\tSize\t\tElement" << endl;
Print( &L );
return 0;
}

void InitList(SqList *L)
{
L -> elem = (int *)malloc(MaxSize * sizeof(int));//分配内存空间,把空间首地址赋给L的成员elem
//分配成功则返回自己指定的类型(int *),若无指定则返回void指针
//分配失败则返回NULL
if(!L -> elem)
{
cout << "Initialized failed" << endl;
exit(0);
}
else
cout << "Initialized successfully" << endl;
cout << "Sequence\tMEM_addr\t\tSize\t\tElement" << endl;
L -> length = 0;
L -> ListSize = MaxSize;
VirValue( L, 0, L->ListSize);                   //原函数声明为void VirValue(SqList *L, int sPos, int ePos);
//而此处赋给的参数却是 L 而非 *L 是因为这里的参数不是从main中传来的,而是从InitList中传的
Print( L );
}

void InsertList(SqList *L,int Pos,int elem)
{
int *base, *insertPtr, *p;
if (Pos < 1 || Pos > L -> length + 1)
{
cout << "Error:Position is illegal!" << endl;
// exit(0);                                        //和return区别见末尾,搞笑,这里如果exit了,那程序就结束了
//根本就脱离了main中while循环的目的。disgusting
}
if (L->length >= L->ListSize)
{
base = (int *)realloc( L->elem,(L->ListSize + Increasment) * sizeof(int) );  //realloc malloc 见末尾
L->elem = base;
L->ListSize += Increasment;
}
VirValue( L, L->length, L->ListSize);             //把刚多分配的内存地址数据赋零
insertPtr = &(L->elem[Pos-1]);
for (p = &( L->elem[L->length-1] ); p >= insertPtr; p--)  //把插入点以后的数据向后移动一个位置,给要插入的元素腾出空间来
{
*(p + 1) = *p;
}
*insertPtr = elem;
L -> length++;
}

void Delete(SqList *L,int Pos)
{
if(Pos < 1 || Pos > L->length)
{
cout << "Error:Position is illegal!" << endl;
}
for (Pos; Pos < L->length; ++Pos)
{
L->elem[Pos-1] = L->elem[Pos];             //把要删除点后面的元素朝前移动一个单元。循环完成后最末元素与倒数第二个元素一样
}
L->elem[Pos] = 0;                              //把最末元素赋0处理
L->length--;
}

void Print(SqList *L)
{
for (int i = 0; i < L -> ListSize; i++)
{
cout << i+1 << "\t\t" << &(L -> elem[i]) << "\t\t" //L -> elem指向顺序表元素的首地址,存储的是顺序表第一个元素
//而 L -> elem[i]则指向第i个元素的地址, &(L -> elem[i])则代表这个地址中所存的数据
<< sizeof(L -> elem[i]) << "\t\t"         //这行有点多余,都是一样的大小,int型(和编译器有关)
<< L -> elem[i] << endl;
}
}

void VirValue(SqList *L, int sPos, int ePos)
{
for (int i = sPos; i < ePos; i++)
{
L->elem[i] = 0;
}
}

/*
1.return exit
exit()子程序终止函数与return()函数的差别

  在main函数中我们通常使用return (0);这样的方式返回一个值。

  但这是限定在非void情况下的也就是void main()这样的形式。

  exit()通常是用在子程序中用来终结程序用的,使用后程序自动结束跳会操作系统。

  但在如果把exit用在main内的时候无论main是否定义成void返回的值都是有效的,并且exit不需要考虑类型,exit(1)等价于return (1)

#include <iostream>
#include <string>
using namespace std;

int main()
{
exit (1);//等价于return (1);
}
2.realloc malloc

C语言的标准内存分配函数:malloc,calloc,realloc,free等。
malloc与calloc的区别为1块与n块的区别:
malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。
calloc调用形式为(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。
realloc调用形式为(类型*)realloc(*ptr,size):将ptr内存大小增大到size。
free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。
C++中为new/delete函数。

realloc详解
1. realloc失败的时候,返回NULL
  2. realloc失败的时候,原来的内存不改变,不会释放也不会移动
  3. 假如原来的内存后面还有足够多剩余内存的话,realloc的内存=原来的内存+剩余内存,realloc还是返回原来内存的地址; 假如原来的内存后面没有足够多剩余内存的话,realloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原来的内存将被free掉,realloc返回新内存的地址
  4. 如果size为0,效果等同于free()
  5. 传递给realloc的指针必须是先前通过malloc(), calloc(), 或realloc()分配的
  6.传递给realloc的指针可以为空,等同于malloc。
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息