数据结构类型:
①集合
结构中数据元素同属于一个集合;
②线性结构
结构中数据元素之间是一对一的关系;
③树形结构
结构中数据元素之间是一对多的关系;
④图状结构
结构中数据元素之前是多对多的关系;
存储映像方法:
显式或隐式地存储数据结构之间的逻辑关系,建立数据的逻辑结构到存储结构的转化;
①顺序方法
将一组结点存放在一片地址连续的存储单元中,结点之间的关系用存储单元的自然顺序关系表示,其优点为节省存储空间,数组采用的即是顺序方法;
②链式方法
在结点的存储结构中附加指针来表示结点之间的逻辑关系;
③索引方法
建立索引函数,把整数索引值映射到结点地址,形成索引表;
④散列方法
设计散列函数,把关键码的值映射到存储空间的地址,然后在次存储单元中存入结点;
线性表:
结构中各元素之间存在一对一的关系和序偶关系;
①顺序表
基本操作:
1.初始化操作InitSqList(SqList &L)
2.判断顺序表是否为空ListIsEmpty(SqList L)
3.求顺序表的长度ListLength(SqList L)
4.取顺序表中的第i个元素GetElem(SqList L,index,ElemType &e)
5.查找元素在顺序表中的位置FindElem(SqList L,ElemType e)
6.插入操作ListInsert(SqList &L,index,ElemType e)
7.删除操作ListDelete(SqList &L,index,ElemType &e)
8.遍历操作ListDisplay(SqList L)
9.建表操作SetList(SqList &L)
代码实现
#include <iostream>
#include <stdlib.h>
using namespace std;
#define ListInitSize 100 //初始顺序表大小
#define ListIncrement 10 //顺序表增量
typedef struct {
int *elem;
int length;
int listsize;
}SqList;
void InitSqList(SqList &L){ //初始化操作
L.elem=(int*)malloc(ListInitSize* sizeof(int));
if(!L.elem) //判断空间是否申请成功
return ;
L.length=0;
L.listsize=ListInitSize;
}
void ListSet(SqList &L,int i,int e){ //把元素存入顺序表中
if(L.length>=L.listsize){ //顺序表的空间不够,需要另外分配空间
int* newelem=(int*)realloc(L.elem,(L.listsize+ListIncrement) *sizeof(int));
if(!newelem) //空间分配失败
return ;
L.elem=newelem;
L.listsize+=ListIncrement;
}
L.elem[i]=e;
L.length++;
}
int ListIsEmpty(SqList L){ //判断顺序表是否为空,length为0即顺序表为空,返回1,反之为0
if(L.length==0)
return 1;
return 0;
}
int ListLength(SqList L){ //求顺序表长度,返回length
return L.length;
}
void GetElem(SqList L,int i){ //取第i个元素,由e返回元素值
if(i<1||i>L.length) { //i值非法
cout << "位置非法!"<<endl;
return;
}
cout<<L.elem[i-1]<<endl;
}
int FindElem(SqList L,int e){ //查找元素位置
int i=0;
while(i<L.length&&L.elem[i]!=e)
i++;
if(i<L.length)
return i+1;
return 0;
}
void ListInsert(SqList &L,int i,int e){ //插入元素操作
if(i<1||i>L.length){
cout<<"位置非法!"<<endl;
return ;
}
if(L.length>=L.listsize){ //顺序表的空间不够,需要另外分配空间
int* newelem=(int*)realloc(L.elem,(L.listsize+ListIncrement) *sizeof(int));
if(!newelem) //空间分配失败
return ;
L.elem=newelem;
L.listsize+=ListIncrement;
}
for(int j=L.length-1;j>=i-1;j--)
L.elem[j+1]=L.elem[j];
L.elem[i-1]=e;
L.length++;
}
void ListDelete(SqList &L,int i){ //删除元素操作
if(i<1||i>L.length) {
cout << "位置非法!"<<endl;
return;
}
cout<<L.elem[i-1]<<endl;
for(int j=i-1;j<L.length;j++)
L.elem[j]=L.elem[j+1];
L.length--;
}
void ListDisplay(SqList L){ //遍历操作
cout<<"顺序表输出:"<<endl;
for(int i=0;i<L.length;i++)
cout<<L.elem[i]<<" ";
cout<<endl;
}
int main(){
SqList L;
InitSqList(L);
cout<<"输入顺序表的大小:";
int n,e,i;
cin>>n;
cout<<"输入数据:";
for (i = 0; i <n; ++i) {
cin>>e;
ListSet(L,i,e);
}
ListDisplay(L);
cout<<"是否空表:";
if(ListIsEmpty(L))
cout<<"空表!"<<endl;
else cout<<"非空!"<<endl;
cout<<"顺序表长度:"<<ListLength(L)<<endl;
cout<<"取哪一个元素:";
cin>>i;
cout<<"所取元素为:";
GetElem(L,i);
cout<<"查找哪个元素:";
cin>>e;
cout<<"查找元素是第"<<FindElem(L,e)<<"个"<<endl;
cout<<"在哪个位置插入什么元素:";
cin>>i>>e;
ListInsert(L,i,e);
ListDisplay(L);
cout<<"删除哪个位置的元素:";
cin>>i;
cout<<"删除的元素为:";
ListDelete(L,i);
ListDisplay(L);
}
例1
顺序表L中的元素递增有序,设计算法,用最少时间在表中查找值为x的元素,若找到将其与后继元素位置交换,若找不到则将其插入表中,顺序表仍有序;
代码实现
void ElemFind(SqList &L,int x){ //直接遍历查找也可以,但有序比较适合折半查找法
int low,high,mid,flag;
low=0;
high=L.length-1;
flag=1;
while(flag&&low<=high){ //折半查找法
mid=(low+high)/2;
if(L.elem[mid]==x)
flag=0;
else if(L.elem[mid]>x)
high=mid-1;
else low=mid+1;
}
if(!flag){ //找到x
if(mid==L.length-1) {
cout << "无后继!" << endl;
return;
}
int temp=L.elem[mid+1];
L.elem[mid+1]=L.elem[mid];
L.elem[mid]=temp;
}
else{ //查找失败,x插入表中
for (int i = L.length; i >low ; i--)
L.elem[i]=L.elem[i-1];
L.elem[mid+1]=x;
L.length++;
}
}
例2
一组整数存储在一个顺序表中,设计算法,在O(n)时间复杂度范围内,将所有负整数放在所有整数的前面;
代码实现
void ListSort(SqList &L){ //O(n)的复杂度意味着只能遍历一次表
int low,high; //low,high下标分别从两边开始遍历
low=0;
high=L.length-1;
while(low<high){
while(low<high&&L.elem[low]<0)
low++;
while(low<high&&L.elem[high]>0)
high--;
int temp=L.elem[high];
L.elem[high]=L.elem[low];
L.elem[low]=temp;
}
}
例3
设计算法,将顺序表中所有元素就地逆置;
代码实现
void ListReverse(SqList &L){
int low,high;
low=0;
high=L.length-1;
while(low<high){
int temp=L.elem[high];
L.elem[high]=L.elem[low];
L.elem[low]=temp;
low++;
high--;
}
}
②链表
基本操作:
1.初始化操作InitLinkList(LinkList &L)
2.建立链表操作CreatLinkList(LinkList &L,int n)
3.判断链表是否为空ListIsEmpty(LinkList L)
4.求链表长度ListLength(LinkList L)
5.取链表中元素GetElem(LinkList L,index)
6.查找元素位置FindElem(LinkList L,int e)
7.插入操作ListInsert(LinkList &L,index,int e)
8.删除操作ListDelete(LinkList &L,index)
9.遍历操作ListDisplay(Linklist L)
单链表 代码实现
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct LNode{
int date;
struct LNode *next;
}LNode,*LinkList;
void InitLinkList(LinkList &L){ //初始化操作
L=(LinkList)malloc(sizeof(LNode));
if(!L)
return ;
L->next=NULL;
}
//建立链表
void TCreateLinkList(LinkList &L,int n){ //有头结点的尾插法
L=(LinkList)malloc(sizeof(LNode));
LinkList pre=L;
for(int i=0;i<n;i++){
LinkList p=(LinkList)malloc(sizeof(LNode));
cin>>p->date;
pre->next=p;
pre=p;
}
pre->next=NULL;
}
void HCreateLinkList(LinkList &L,int n){ //有头结点的头插法
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
for(int i=0;i<n;i++){
LinkList p=(LinkList)malloc(sizeof(LNode));
cin>>p->date;
p->next=L->next;
L->next=p;
}
}
int ListIsEmpty(LinkList L){ //判断链表是否为空
if(!L->next)
return 1;
return 0;
}
int ListLength(LinkList L){ //求链表的长度
int count=0;
LinkList p=L->next;
while(p){
count++;
p=p->next;
}
return count;
}
void GetElem(LinkList L,int i){ //取链表元素
int j=1;
LinkList p=L->next;
while(p&&j<i){
j++;
p=p->next;
}
if(j>i||!p){
cout<<"位置非法!"<<endl;
return ;
}
cout<<p->date<<endl;
}
int FindElem(LinkList L,int e){ //查找元素
LinkList p=L->next;
int j=1;
while(p&&p->date!=e) {
j++;
p = p->next;
}
if(!p)
return 0;
return j;
}
void ListInsert(LinkList &L,int i,int e){ //插入元素
int j=1;
LinkList p=L->next;
while(p&&j<i-1){
j++;
p=p->next;
}
if(!p||j>i-1){
cout<<"位置非法!"<<endl;
return ;
}
LinkList s=(LinkList)malloc(sizeof(LNode));
s->date=e;
s->next=p->next;
p->next=s;
}
void ListDelete(LinkList &L,int i){ //删除元素
int j=1;
LinkList p=L->next;
while(p&&j<i-1){
j++;
p=p->next;
}
if(!p||j>i-1){
cout<<"位置非法!"<<endl;
return ;
}
LinkList s=p->next;
p->next=s->next;
cout<<s->date<<endl;
}
void ListDisplay(LinkList L){ //链表输出
cout<<"链表输出:"<<endl;
LinkList p=L->next;
while(p){
cout<<p->date<<" ";
p=p->next;
}
cout<<endl;
}
int main(){
LinkList L;
InitLinkList(L);
cout<<"输入顺序表的大小:";
int n,e,i;
cin>>n;
cout<<"输入数据:";
TCreateLinkList(L,n);
ListDisplay(L);
cout<<"是否空表:";
if(ListIsEmpty(L))
cout<<"空表!"<<endl;
else cout<<"非空!"<<endl;
cout<<"顺序表长度:"<<ListLength(L)<<endl;
cout<<"取哪一个元素:";
cin>>i;
cout<<"所取元素为:";
GetElem(L,i);
cout<<"查找哪个元素:";
cin>>e;
cout<<"查找元素是第"<<FindElem(L,e)<<"个"<<endl;
cout<<"在哪个位置插入什么元素:";
cin>>i>>e;
ListInsert(L,i,e);
ListDisplay(L);
cout<<"删除哪个位置的元素:";
cin>>i;
cout<<"删除的元素为:";
ListDelete(L,i);
ListDisplay(L);
}