目录
#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;
#define InitSize 10 //默认的最大长度
typedef struct{
int *data; //指示动态分配数组的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表的当前长度
}SeqList;
//初始化
void InitList (SeqList &L){
L.data=(int *)malloc(InitSize *sizeof(int));
L.length=0;
L.MaxSize=InitSize;
}
//动态增加数组的长度
void IncreaseSize (SeqList &L,int len){
int *p=L.data;
L.data=(int *)malloc((L.MaxSize+len)*sizeof(int));
for(int i=0;i<L.length;i++)
{
L.data[i]=p[i];
}
L.MaxSize=L.MaxSize+len;
free(p);
}
//插入--在L的位序i处插入元素e
bool ListInsert(SeqList &L,int i,int e){
if(i<1||i>L.length+1) //判断i是否有效
return false;
if(L.length>=L.MaxSize) //当前存储空间已满,不能插入
return false;
for(int j=L.length;j>=i;j--) //将第i个元素及之后的元素后移
{
L.data[j]=L.data[j-1];
}
L.data[i-1]=e; //在位置i处放入e
L.length++; //长度加1
return true;
}
//删除--在L的位序i处删除元素e
bool ListDelete(SeqList &L,int i,int e){
if(i<1||i>L.length+1) //判断i是否有效
return false;
e=L.data[i-1];
for(int j=i;j<L.length;j++) //将第i个元素后的元素前移
{
L.data[j-1]=L.data[j];
}
L.length--; //长度减1
return true;
}
//按位查找
ElemType GetElem(SeqList L,int i){
return L.data[i-1];
}
//按值查找
ElemType LocateElem(SeqList L,ElemType e){
for(int i=0;i<L.length;i++)
if(L.data[i]==e) //下标为i的元素值=e,返回其位序i +1
return i+1;
return 0; //退出循环,说明查找失败
}
//输出
void out(SeqList &L){
for(int i=0;i<L.length;i++)
{
cout<<L.data[i];
}
cout<<endl;
}
void ints(SeqList &L){
for(int i=0;i<L.length;i++)
{
cin>>L.data[i];
}
cout<<endl;
}
int main(){
SeqList L; //声明一个顺序表
InitList(L); //初始化顺序表
IncreaseSize(L,5);
ListInsert(L,3,3);
int e=-1;
if(ListDelete(L,3,e))
cout<< "已删除第3个元素,删除元素为"<<e;
else
cout<<"位序i不合法,删除失败"<<endl;
out(L);
return 0;
}
1.单链表
1.1带头结点
//顺序表——单链表 ——带头节点
#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;
//定义一个单链表
typedef struct LNode{ //LNode:结点
int data; //data:数据域
struct LNode *next; //指向下一个结点的指针
}LNode,*LinkList;
//free(p);
//初始化一个空的单链表
bool InitList(LinkList &L){
L = (LNode *) malloc(sizeof(LNode)); //分配一个头结点
if(L==NULL) //内存不足,分配失败
return false;
L->next=NULL; //头结点不存储数据
return true;
}
void test(){
LinkList L;
InitList(L);
}
1.1.1 按位序插入
//顺序表——单链表——按位序插入(带头结点)
bool InsertNextNode (LNode *p,ElemType e);
//在第i个位置插插入元素e (带头结点)
bool ListInsert(LinkList &L, int i,ElemType g){
if(i<1)
return false;
LNode *p; //指针p指向当前扫描到的结点
int j=0; //当前p指向的是第几个结点
p = L; //L指向头结点,头结点是第0个结点(不存数据)
//循环找到第i-1个结点
while (p!=NULL && j<i-1) {
p=p->next;
j++;
}
return InsertNextNode (p,e);
}
1.1.2前插操作
//顺序表——单链表 ——带头节点——前插操作:在p结点之前插入元素e
bool InsertNextNode (LNode *p,ElemType e){
if (p==NULL)
return false;
LNode *s = ( LNode *)malloc(sizeof( LNode) );
if (s==NULL) //内存分配失败
return false;
s->next=p->next;
p->data = s; //新结点s连接到P之后
s->data=p->data; //将p中的元素复制到s之中
p->next=e; //覆盖
return true;
}
1.1.3 后插操作
//后插操作:在p结点之后插入元素e
bool InsertNextNode (LNode *p,ElemType e){
if (p==NULL)
return false;
LNode *s = ( LNode *)malloc(sizeof( LNode) );
if (s==NULL) //内存分配失败
return false;
s->data = e; //用结点s保存数据元素e
s->next=p->next;
p->next=s; //将结点s连到p之后
return true;
}
1.1.4删除操作
//顺序表——单链表 ——带头节点——删除操作
bool ListDelete(LinkList &L, int i,ElemType &e){
if(i<1)
return false;
LNode *p; //指针p指向当前扫描到的结点
int j=0; //当前p指向的是第几个结点
p = L; //L指向头结点,头结点是第0个结点(不存数据)
while (p!=NULL && j<i-1) //循环找到第i-1个结点
p=p->next;
j++;
}
if(p==NULL) //i值不合法
return false;
if( p->next == NULL) //第i-1个结点之后已无其他结点
return false;
LNode *q=p->next; //令q指向被删除结点
e = q->data; //用e返回元素的值
p->next=q->next; //将*q结点从链中断开
free(q); //释放结点的存储空间
return true; //删除成功
}
1.2不带头结点
//顺序表——单链表 ——不带头节点
#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;
//定义一个单链表
typedef struct LNode{ //LNode:结点
int data; //data:数据域
struct LNode *next; //指向下一个结点的指针
}LNode,*LinkList;
LNode * p = (LNode *) malloc(sizeof(LNode)); //增加一个新的结点:在内存中申请一个结点所需要的空间,并用指针P指向这个结点
//free(p);
//初始化一个空的单链表
bool InitList(LinkList &L){
L=NULL; //空表,暂时还没有任何结点,防止脏数据
return true;
}
//判断单链表是否为空
bool Empty(LinkList L){
if(L==NULL)
return true;
else
return false;
}
void test(){
LinkList L;
InitList(L);
}
1.2.1 按位序插入
//顺序表——单链表——按位序插入(不带头结点)
//在第i个位置插插入元素e (不带头结点)
bool ListInsert(LinkList &L, int i,ElemType g){
if(i<1)
return false;
//如果不带头结点,则插入、删除第1个元素时,需要更改头指针L
if(i==1){
LNode *s = ( LNode *)malloc(sizeof( LNode) ); //申请新的结点空间
s->data = e;
s->next=L;
L=s;
return true;
}
//i>1的情况
LNode *p; //指针p指向当前扫描到的结点
int j=1; //当前p指向的是第几个结点
p = L; //L指向头结点,头结点是第0个结点(不存数据)
//循环找到第i-1个结点
while (p!=NULL && j<i-1) {
p=p->next;
j++;
}
//i值不合法
if(p==NULL)
return false;
LNode *s = ( LNode *)malloc(sizeof( LNode) ); //申请新的结点空间
s->data = e;
s->next=p->next;p->next=s; //将结点s连到p之后
return true; //插入成功
}
2.双链表
//顺序表——双链表
#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;
//定义一个双链表
typedef struct DNode{ //LNode:结点
int data; //data:数据域
struct DNode *prior,*next; //指向下一个结点的指针
}DNode,*DLinkList;
//初始化一个空的双链表
bool InitDList(DLinkList &L){
L = (DNode *) malloc(sizeof(DNode)); //分配一个头结点
if(L==NULL) //内存不足,分配失败
return false;
L->next=NULL; //头结点不存储数据
L->prior=NULL;
return true;
}
//在p结点之后插入s结点
bool InsertNextDNode( DNode *p,DNode *s){
if ( p==NULL ls==NULL)//非法参数
return false;
s->next=p->next; //将结点*s插入到结点*p之后
if (p->next != NULL) //如果p结点有后继结点
p->next->prior=s;
s->prior=p;
p->next=s;
}
//删除p结点的后继结点
bool DeleteNextDNode( DNode *p){
if ( p==NULL)
return false;
DNode *q = p->next; //找到p的后继结点q
if (q==NULL)
return false; // p没有后继
p->next=q->next;
if (q->next !=NULL)//q结点不是最后一个结点
q->next->prior=p;
free(q);//释放结点空间
return true;
}
//销毁双链表
void DestoryList(DLinklist &L){
//循环释放各个数据结点
while (L->next != NULL)
DeleteNextDNode(L);
free(L); //释放头结点
L=NULL; //头指针指向NULL
}
void test(){
LinkList L;
InitDLinkList(L);
}