数据结构与算法 --C++

数据结构与算法

函数结果状态代码

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#INFEASIBLE -1
#OVERFLOW -2
typedef int Status;
typedef char ElemType;

1.线性表

结构体

define MAXSIZE 100
typedef struct{
	ElemType *elem;
	int length;
} SqList;   
1) 线性表L的初始化
Status InitList_Sq(SqList &L){   //构造一个空的顺序表
	L.elem = new ElemType[MAXSIZE]; //为顺序表分配空间
	if(!L.elem) exit(OVERFLOW);   //存储分配失败
	L.length = 0;         //空表长度为0
	return OK;
}  
2) 查找
int LocateElem(SqList L, ElemType e){ 
  for(i = 0; i < L.length; i++) 
    if(L.elem[i] == e)  return i+1;
  return 0;
}
3) 插入
Status ListLnsert_Sq(SqList &L, int i, ElemType e){
  if(i < 1 || i > L.length+1)  return ERROR;  //i值不合法
  if(L.length == MAXSIZE)  return ERROR;  //当前存储空间已满
  for(j = L.length-1; j >= i-1; j--)
    L.elem[j+1] = L.elem[j];  //插入位置及之后的元素后移
  L.elem[i-1] = e;        //将新元素e放入第i个位置
  L.length++;          //表长增1
  return OK;
}
4)线性表的合并
  • 问题描述:假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合A=A∪B
    La=(7,5,3,11) Lb=(2,6,3) ----------> La=(7,5,3,11,2,6)
  • 算法步骤: 依次取出Lb中的每个元素
    1. 在La中查找该元素
    1. 如果找不到,则将其插入La的最后
void union(List &La, List Lb){
	La_len = ListLength(La);
	Lb_len = ListLength(Lb);
	for(i=1; i<=Lb_len; i++){
		GetElem(Lb,i,e);
		if(!LocateElem(La,e))	ListInsert(&La,La_len++,e);
	}
}
5)有序表的合并
  • 问题描述:已知线性表La和Lb中的数据元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列
    La={1,7,8} Lb={2,4,6,8,10,11} -------> Lc=

  • 算法步骤:

    1. 创建一个空表Lc
    1. 依次从La或Lb中”摘取“元素值较小的结点插入到Lc表的最后,直至其中一个表变空为止
    1. 继续将La或Lb其中一个表的剩余结点插入在Lc表的最后
void MergeList_Sq(SqList LA, SqList LB, SqList &LC){
	pa = LA.elem;	//pa = LA.elem[0]
	pb = LB.elem;	//指针pa和pb的初值分别指向两个表的第一个元素
	LC.length = LA.length + LB.length;	//新表长度为待合并量表的长度之和
	LC.elem = new ElemType[LC.length];	//为合并后的新表分配一个数组空间
	pc = LC.elem;	//指针pc指向新表的第一个元素
	pa_last = LA.elem + LA.length -1;	//指针pa_last指向LA表的最后一个元素
	pb_last = LB.elem + LB.length -1;	//指针pb_last指向LB表的最后一个元素
	while(pa<=pa_last && pb<=pb_last){	//两个表都非空
		if(*pa<=*pb)	*pc++=*pa++;		//依次”摘取“两表中值较小的结点
		else			*pc++=*pb++;
	}
	while(pa<=pa_last)	*pc++=*pa++;		//LB表已到达表尾,将LA中剩余元素加入LC
	while(pb<=pb_last)	*pc++=*pb++;	//LA表已到达表尾,将LB中剩余元素加入LC
}
	//这里的LA.elem+LA.length-1就等同于LA.elem[0+La.length-1]
6)删除数据
bool DeleteData(SqList &pa, int n){
  if((n<1) || (n > pa.length + 1))
    return false;    //返回值为错误
   for(int i = 1; i < pa.length - 1; i++)
    pa.elem[i-1] = pa.elem[i];  //删除数据后,将数据所对应的线性表进行修改
  pa.length--;      //线性表的长度将减少
  return true;      //返回值为正确
}

2.单链表

结构体

typedef struct Lnode{
  ElemType data;
  struct Lnode *next;
}LNode,*LinkList;  
1) 初始化
Status InitList_L(LinkList &L){
  L = new LNode;
  L->next = NULL;
  return OK;
}
2) 判断链表是否为空
int ListEmpty(LinkList L){
  if(L->next)
    return 0;
  else
    return 1;
}
3) 单链表的销毁
Status DestroyList_L(LinkList &L){
  Lnode *p; //或LinkList p;
  while(L){
    p = L;
    L = L->next;
    delete p;
}
4) 清空链表
Status ClearList(LinkList &L){
  Lnode *p,*q;  //或LinkList p,q;
  p=L->next;
  while(p){
    q = p->next;
    delete p;
    p = q;
  }
  L->next = NULL;
  return OK;
}
5) 单链表的表长
int ListLength_L(LinkList L){  //返回L中数据元素个数
  LinkList p;
  p = L->next;        //p指向第一个结点
  i = 0;
  while(p){          //遍历单链表,统计结点数
    i++;
    p = p->next;
  }
  return i;
}
6) 单链表的取值
Status GetElem_L(LinkList L, int i, ElemType &e){  //获取线性表L中的某个数据元素的内容,通过变量e返回
  p = L->next;  j = 1;
  while(p && j < i){    //向后扫描,直到p指向第i个元素或p为空
    p=p->next; j++;
  }
  if(!p || j>i)  return ERROR;  //第i个元素不存在
  e = p->data;      //取第i个元素
  return OK;
}  //GetElem_L
7) 单链表的查找
  • 按值查找:根据指定数据获取该数据所在的位置(该数据的地址)
Lnode *LocateELem_L(LinkList L, Elemtype e){
//在线性表L中查找值为e的数据元素
//找到,则返回L中值为e的数据元素的地址,查找失败返回NULL
  p = L->next;
  while(p && p->data != e)
    p = p->next;
  return p;
}
  • 按值查找:根据指定数据获取该数据所在的位置序号(是第几个数据元素)
//在线性表L中查找值为e的数据元素的位置序号
int LocateELem_L(LinkList L, Elemtype e){
//返回L中值为e的数据元素的位置序号,查找失败返回0
  p = L->next;  j = 1;
  while(p && p->data != e){
    p = p->next;
    j++;
  }
  if(p)  return j;
  else   return 0;
}
8) 单链表的插入
//在L中第i个元素之前插入数据元素e
Status ListInsert_L(LinkList &L, int i,ElemType e){
  p = L;  j = 0;
  while(p && j<i-1){
    p = p->next; j++;            //寻找第i-1个结点,p指向i-1结点
  }
  if(!p || j>i-1)  return ERROR;  //i大于表长+1或者小于1,插入位置非法
  s = new LNode;  s->data = e;    //生成结点s,将结点s的数据域置为e
  s->next = p->next;            //将结点s插入L中
  p->next = s;
return OK
}    //ListInsert_L
9) 单链表的删除
//将线性表L中第i个数据元素删除
Status ListDelete_L(LinkList &L, int i, ElemType &e){
  p = L;  j = 0;
  while(p->next && j<i-1){
    p = p->next;
    j++;
  }      //寻找第i个结点,并令p指向其前驱
  if(!(p->next) || j>i-1)  return ERROR;  //删除位置不合理
  q = p->next;        //临时保存被删结点的地址以备释放
  p->next = q->next;    //改变删除结点前驱结点的指针域
  e = q->data;          //保存删除结点的数据域
  delete q;            //释放删除结点的空间
  return OK;
}  //ListDelete_L
10)单链表的建立
  • 头插法
void CreateList_H(LinkList &L, int i){
  L = new LNode;
  L->next = NULL;
  for(i=n;i>0;i--){
    p = new LNode;
    cin >> p->data;
    p->next = L->next;    //插入到表头
    L->next = p;
  }
}        
  • 尾插法
void CreateList_T(LinkList &L, int n){
  L = new LNode;
  L->next = NULL;
  r = L;      //尾指针r指向头结点
  for(i=1; i<=n; i++){
    p = new LNode;
    cin >> p->data;
    p->next = NULL;
    r->next = p;      //插入到表尾
    r = p;          //r指向新的尾结点
  }
}

3.单循环链表(表的操作常常是在表的首尾位置上进行)

循环链表

带尾指针循环链表的而合并(将Tb合并在Ta之后)
LinkList Connect(LinkList &Ta, LinkList &Tb){
//假设Ta,Tb都是非空的单循环链表
	p = Ta->next;		//p存储头结点
	Ta->next = Tb->next->next;	//Tb表头连结Ta表尾
	delete Tb->next;	//释放Tb表头结点
	Tb->next = p;		//修改指针
	return Tb;			
}

4.双向链表

  • 在单链表的每个结点里再增加一个指向其直接前驱的指针域,这样链表中就形成了有两个方向不同的链

双向循环链表:

  • 让头结点的前驱指针指向链表的最后一个结点
  • 让最后一个结点的后继指针指向头结点

双向链表结构的对称性(设指针p指向某一结点)

  • p->prior->next = p = p-next->prior

结构体定义

typedef struct DuLNode{
	Elemtype data;
	struct DuLNode *prior, *next;
}DuLNode, *DuLinkList;
1)双向链表的插入
//在常头结点的双向循环链表L中第i个位置之前插入元素e
void ListInsert_DuL(DuLinkList &L, int i, ElemType e){
	if(!(p = GetElemP_DuL(L,i)))	return ERROR;
	s = new DuLNode;			s->data = e;
	s->prior = p->prior;			p->prior->next = s;
	s->next = p;				p->prior = s;
	return OK;
}//ListInsert_DuL
2)双向链表的删除
void ListDelete_DuL(DuLink &L, int i, ElemType &e){
//删除带头结点的双向循环链表L的第i个元素,并用e返回
	if(!(p = GetElemP_DuL(L,i)))	return ERROR;
	e = p->data;
	p->prior->next = p->next;
	p->next->prior = p->prior;
	delete p;
	return OK;
}//ListDelete_DuL
posted @   cherishviki  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示