数据结构——线性结构总结
线性数据结构
-
数组
-
链表
-
栈
-
队列
线性数据结构的特征(在数据元素的非空有限集中) -
数据结构中有且只有一个首元素和尾元素
-
数据结构中的中间元素只有一个前驱和后继同理首元素和尾元素只有一个后继和前驱
数据元素的存储(顺序存储和链式存储)和数据元素的操作(插入和删除)是数据结构的重要部分。
数据结构中的线性结构可分为线性表,栈和队列。对于这三种结构,有两种存储方式顺序存储和链式存储以两种主要操作,插入和删除。不同线性结构的插入和删除操作的方式不同,而且不同存储方式在插入和删除的效率上也有所不同。
顺序存储
#define MAX_SIZE 100
typedef int ElementType;
typedef struct sqlist{
ElementType *elem; //存储空间的基地址
int length; //当前长度
int listsize; //当前存储空间的大小
}Sqlist;
int init(Sqlist &L) // 初始化
{
L.elem = (ElementType*)malloc(MAX_SIZE*sizeof(ElementType));
if(!L.elem) exit(0);
L.length=0;
L.listsize = MAX_SIZE;
return 1;
}
int inser(Sqlist &L, int i, ElementType e) //插入操作
{
//i的合法值是[0,length]
//i的意思表示在第i个位置之前插入新元素,i=length时表示在list末尾插入新元素
if(i<0||i>L.length)return 0;
if(L.listsize<=L.length)
{
ElementType *newbase = (ElementType*)realloc(L.elem,((MAX_SIZE+L.listsize)*sizeof(ElementType)));
if(!newbase)exit(0);
L.elem = newbase;
L.listsize +=MAX_SIZE;
}
for(int j=L.length;j>i;j--)L.elem[j]=L.elem[j-1];
L.elem[i] = e;
L.length++;
return 1;
}
int delet(Sqlist &L,int i,ElementType &e)
{
//删除第i个位置上的元素并用e返回其值
//i的合法值是[0,length-1]
if(i<0||i>L.length-1)return 0;
e = L.elem[i];
for(int j=i;j<L.length-1;j++)L.elem[j]=L.elem[j+1];
L.length--;
return 1;
}
int cmpEqual(ElementType a, ElementType b)
{
return a==b;
}
int cmpGreat(ElementType a, ElementType b)
{
return a>b;
}
int cmpLess(ElementType a, ElementType b)
{
return a<b;
}
int fin(Sqlist &L, ElementType e,int (*cmp)(ElementType, ElementType))
{
//查找L中第一个与e满足cmp关系的元素的位序[0,length-1],如果没有则返回-1
//cmp是比较函数,如果满足cmp的比较条件则返回1,否则返回0
int i=0;
for(i=0;i<L.length;i++)
{
if((*cmp)(L.elem[i],e))return i;
}
return -1;
}
链式结构
typedef int ElementType;
typedef struct Lnode{
ElementType data;
Lnode* next;
}Lnode, *Lnodelist;
void createList(Lnodelist &l,int n)
{
/*通过控制台的输入,创建大小为n的链表
两种创建方式,头插法创建的链表和输入顺序相反,尾插法创建的链表和输入顺序相同*/
l = (Lnode*)malloc(sizeof(Lnode));
l->next=NULL;
Lnode *p;
/*
Lnode *q = l;
for(int i=0;i<n;i++)//尾插法
{
p = (Lnode*)malloc(sizeof(Lnode));
cin>>p->data;
p->next = q->next;
q->next = p;
q = p;
}
*/
for(int i=n;i>0;i--) //头插法
{
p=(Lnode*)malloc(sizeof(Lnode));
cin>>p->data;
p->next=l->next;
l->next = p;
}
}
int getElem(Lnodelist &l,int i,ElementType&e)
{
/*返回单链表中第i个元素,i的取值范围是[1,n];*/
Lnode *p= l->next;
int j=1;
while(p&&j<i)
{
p=p->next;
j++;
}
if(!p||j>i)return 0; /*此处判断j>i的原因是,如果传入的i小于1时能够及时报错。*/
e = p->data;
return 1;
}
int listInser(Lnodelist &l,int i,ElementType e)
{
/*在链表第i个位置之前插入元素e,i的取值范围[1, n]*/
Lnode *p = l,*newP;
int j=0;
while(p&&j<i-1)
{
p=p->next;
j++;
}
if(!p||j>i-1)return 0; /*此处判断j>i-1的原因是,如果传入的i小于1时能够及时报错。*/
newP = (Lnode*)malloc(sizeof(Lnode));
newP->data = e;
newP->next = p->next;
p->next = newP;
return 1;
}
int listDel(Lnodelist &l,int i,ElementType &e)
{
/*删除链表中第i个元素,并用e返回其值,i的取值范围是[1, n]*/
Lnode *p= l,*q;
int j=0;
while(p->next&&j<i-1)
{
p = p->next;
j++;
}
if(!p->next||j>i-1)return 0;/*此处判断j>i-1的原因同上*/
q = p->next;
p->next = q->next;
e =q->data;
free(q);
return 1;
}
栈 是一个先进后出原则线性表
#define STACK_SIZE 100
typedef int SelemType;
typedef struct Stack{
SelemType *base; //存放数据的数组
SelemType *top; //栈顶指针,指向栈顶元素上面的地址
int stacksize; //栈的大小
}Sqstack;
int initS(Sqstack &s)
{
s.base = (SelemType*)malloc(STACK_SIZE*sizeof(SelemType));
if(!s.base)exit(0);
s.top=s.base;
s.stacksize = STACK_SIZE;
return 1;
}
int getTop(Sqstack &s,SelemType &e)
{
//如果不是空栈,则将栈顶元素返回到e,并返回1,否则返回0
if(s.top==s.base)return 0;
e = *(s.top-1);
return 1;
}
int push(Sqstack &s,SelemType e)
{
//元素e入栈,成功则返回1
if(s.top-s.base>=s.stacksize)//栈满,追加空间
{
s.base = (SelemType*)realloc(s.base,((s.stacksize+STACK_SIZE)*sizeof(SelemType)));
if(!s.base)exit(0);
s.top = s.base+s.stacksize; //因为栈数据空间的base指针改变,所以需要更新栈顶top指针;如果top只是一个索引值(整数型),则不必改变。
s.stacksize +=STACK_SIZE;
}
*s.top=e;
s.top++;
return 1;
}
int pop(Sqstack &s, SelemType &e)
{
//若栈不空,则删除栈顶元素,并通过e返回其值,函数返回1,否则,函数返回0
if(s.top==s.base)return 0;
s.top--;
e = *s.top;
return 1;
}
链栈
typedef struct snode{
SelemType data;
struct snode* next;
}*Snode;
typedef struct Lstack{
Snode stk;
}LStack;
int LinitS(LStack &s)
{
s.stk = (Snode)malloc(sizeof(struct snode));
s.stk->next=NULL;
return 1;
}
int LgetTop(LStack &s,SelemType &e)
{
//如果不是空栈,则将栈顶元素返回到e,并返回1,否则返回0
if(s.stk->next==NULL)return 0;
e = s.stk->next->data;
return 1;
}
int Lpush(LStack &s,SelemType e)
{
//元素e入栈,成功则返回1
Snode newp = (Snode)malloc(sizeof(struct snode));
if(!newp)exit(0);
newp->data = e;
newp->next= s.stk->next;
s.stk->next = newp;
return 1;
}
int Lpop(LStack &s, SelemType &e)
{
//若栈不空,则删除栈顶元素,并通过e返回其值,函数返回1,否则,函数返回0
if(s.stk->next==NULL)return 0;
Snode temp = s.stk->next;
s.stk->next = temp->next;
e = temp->data;
free(temp);
return 1;
}
队列
typedef int QElemType;
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*Qptr;
typedef struct linkQ{
Qptr fron; //队头指针
Qptr rear; //队尾指针
}LinkQ;
int InitQ(LinkQ &Q)
{
//队列初始化为空
Q.fron =Q.rear = (Qptr)malloc(sizeof(QNode));
if(!Q.fron)exit(0);
Q.fron->next=NULL;
return 1;
}
int DesQ(LinkQ &Q)
{
//销毁队列Q
while(Q.fron)
{
Q.rear = Q.fron->next;
free(Q.fron);
Q.fron = Q.rear;
}
return 1;
}
int EnQ(LinkQ &Q,QElemType e)
{
//入队操作
Qptr p =(Qptr)malloc(sizeof(QNode));
if(!p)exit(0);
p->data = e;
p->next= Q.rear->next;
Q.rear->next = p;
Q.rear=p;
return 1;
}
int DeQ(LinkQ &Q,QElemType &e)
{
//出队操作,用e返回其值
if(Q.fron==Q.rear)return 0;
Qptr p = Q.fron->next;
Q.fron->next = p->next;
e = p->data;
if(Q.rear==p)Q.rear = Q.fron;
free(p);
return 1;
}
相关stl容器
list
c++ reference
List是stl实现的双向链表,与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。使用时需要添加头文件#include
- listlst1; //创建空list
- list lst2(5); //创建含有5个元素的list
- listlst3(3,2); //创建含有3个元素的list,三个元素的初始值是1
- listlst4(lst2); //使用lst2初始化lst4
- listlst5(lst2.begin(),lst2.end()); //同lst4
Lst1.assign() 给list赋值
Lst1.back() 返回最后一个元素
Lst1.begin() 返回指向第一个元素的迭代器
Lst1.clear() 删除所有元素
Lst1.empty() 如果list是空的则返回true
Lst1.end() 返回末尾的迭代器
Lst1.erase() 删除一个元素
Lst1.front() 返回第一个元素
Lst1.get_allocator() 返回list的配置器
Lst1.insert() 插入一个元素到list中
Lst1.max_size() 返回list能容纳的最大元素数量
Lst1.merge() 合并两个list
Lst1.pop_back() 删除最后一个元素
Lst1.pop_front() 删除第一个元素
Lst1.push_back() 在list的末尾添加一个元素
Lst1.push_front() 在list的头部添加一个元素
Lst1.remove() 从list删除元素
Lst1.resize() 改变list的大小
Lst1.reverse() 把list的元素倒转
Lst1.size() 返回list中的元素个数
Lst1.sort() 给list排序
stack
C++ Stack(堆栈) 是一个容器类的改编,为程序员提供了堆栈的全部功能,——也就是说实现了一个先进后出(FILO)的数据结构。
头文件为:
#include
c++ stl栈stack的成员函数介绍
empty() 堆栈为空则返回真
pop() 移除栈顶元素
push() 在栈顶增加元素
size() 返回栈中元素数目
top() 返回栈顶元素
queue
C++队列queue模板类的定义在头文件中,queue 模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque 类型。
C++队列Queue是一种容器适配器,它给予程序员一种先进先出(FIFO)的数据结构。
C++队列Queue类成员函数如下:
back()返回最后一个元素
empty()如果队列空则返回真
front()返回第一个元素
pop()删除第一个元素
push()在末尾加入一个元素
size()返回队列中元素的个数
代码取自他人
原文:https://blog.csdn.net/github_38225139/article/details/80618497