【数据结构】图的基本操作

这篇具有很好参考价值的文章主要介绍了【数据结构】图的基本操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、问题描述

分别以邻接矩阵和邻接表作为存储结构,实现以下图的基本操作:

  • 增加一个新结点v,Insert(G,v);
  • 删除顶点v及其相关的边,Delete(G,v);
  • 增加一条边<v,w>,Insert(G,v,w);
  • 删除一条边<v,w>,Delete(G,v,w);

二、设计思路

1、邻接矩阵实现:

        邻接矩阵实现图的基本操作,主要通过二维数组寻址方式进行数据处理。函数包括:邻接矩阵创建并存储数据、顶点寻址、增加顶点、删除顶点、增加边、删除边、邻接矩阵打印。

        邻接矩阵创建并存储,先根据输入的总顶点数、边数对二维数组初始化,边权为MaxInt,表示两点无关联。将顶点信息存储至顶点数组集中。存储数据时,依次循环根据输入边相关的两点以及权重,先通过顶点寻址函数寻找两点位置,后利用二维数组将矩阵相应位置边权赋予新值,完成数据存储。

        顶点寻址函数设计,只需根据顶点信息,在顶点数组集中遍历,返回其对应数组下标即可。

        增加顶点时,在顶点数组集中增加一位,并将邻接矩阵中多加的一行一列赋值为MaxInt。

        删除顶点时,需要通过数组移动,列方面从待删点开始右侧数据,全部左移;行方面从待删顶点开始下方数据,全部上移。最后删除顶点在顶点数组中的位置。上述操作通过数组移动实现开销较大,也可以在删除时,将最后一个顶点相关信息替代删除顶点,因为本身顶点在数组中的位置无现实意义,可减少算法时间复杂度。

        增加边时,通过顶点寻址函数获取两个顶点位置,通过二维数组将邻接矩阵中对应的边权赋予新值即可。

        删除边时,通过顶点寻址函数获取两个顶点位置,通过二维数组将邻接矩阵中对应的边权赋予MaxInt即可。

        邻接矩阵打印,只需通过二维数组,将其各行各列依次输出,为了增加矩阵可观性,可输出行名、列名以及控制权重输出格式。

        最后通过主函数测试上述所有的函数。

2、邻接表实现:

        邻接表实现图的基本操作,主要通过数组+链表方式进行数据处理。函数包括:邻接表创建并存储数据、顶点寻址、增加顶点、删除顶点、增加边、删除边、邻接表打印。

        邻接表创建并存储,先根据输入的总顶点数、边数对邻接表初始化,数组单元接收顶点信息,由于开始无边,将各单元firstarc指针赋NULL,避免野指针。存储边信息时,创建两个边结点并创建相应指针,在边结点中存储边权以及关联点通过顶点寻址函数查找的下标(如a、b两个顶点,则边结点e1中adjvex存放为b的下标,边结点e2中adjvex存放为a的下标)。并将边结点插入各自数组单元的关联顶点链表首结点(即被各单元firstarc指针指向)。

        顶点寻址函数设计,只需根据顶点信息,在顶点数组集中遍历,返回其对应数组下标即可。

        增加顶点,只需在邻接表数组单元vertices中存储新的顶点信息,并将其firstarc指针赋值为NULL。

        删除顶点,下述操作:先删除待删顶点中所有关联顶点链表中其他顶点信息 ;用最后一个顶点替代删除结点位置(目的在于避免顶点表中出现废弃点占位情况)。实现操作需要遍历邻接表数组单元vertices中关联顶点链表中所有的adjvex,与待删顶点的位置下标比对,相同时删除该结点。结点删除时,需要单独优先考虑表头首结点元素中adjvex是否为待删结点下标,循环删除至表头结点adjvex不为待删结点下标为止,遍历后续所有结点(优先考虑的原因是表头结点有一个firstarc指向问题,不考虑则会出现断链情况)。删除完待删结点在其他单元的信息时,循环待删结点所在单元格关联顶点链表所有结点,将firstarc赋值为NULL。最后将数组vertices中最后一个顶点替代待删结点位置(数组前移覆盖会增加额外的开销)。

        增加边即为上述邻接表存储步骤单次操作,通过创建两个边结点,分别赋值相应数据后,插入两个对应vertices单元格的关联顶点链表的表头(即成为首结点)。

        删除边,即为删除顶点中单次操作,先定位待删边的两个顶点位置,然后遍历两个顶点对应数组vertices单元中的关联顶点链表,查找adjvex的值,删除含有对应顶点位置的边结点,同样注意单独考虑首结点是否含有删除对应顶点位置信息。

        用于删除函数多次使用,因此在优化时,将输出函数提取。

        邻接表打印时,依次访问vertices所有单元中的关联顶点链表,输出所有其中边结点的adjvex对应的顶点信息以及边权。

        最后通过主函数测试上述所有函数。

三、代码展示

1、邻接矩阵实现:

#include<iostream>
using namespace std;
typedef int Status;
#define OK 1
#define ERROR -1
#define MaxInt 32767			//初始化边权无穷大
#define MVNum 100
#define VerTexType char
#define ArcType int

typedef struct AMGraph{		//定义邻接矩阵
 VerTexType vexs[MVNum];   	//创建顶点集
 ArcType arcs[MVNum][MVNum];  //创建邻接矩阵
 int vexnum,arcnum;   			//存放当前图的总顶点数和边数
};

int VexLocate(AMGraph &G,VerTexType u){	//返回顶点在顶点集的位置
 for(int i=0;i<G.vexnum;i++){		//循环遍历顶点集
  if(u==G.vexs[i]) return i;		//找到顶点返回其数组下标
 }
 return -1;
}

Status UDNCreate(AMGraph &G){		//无向邻接矩阵创建并存储数据
 cout<<"请输入无向图总顶点数和总边数:";
 cin>>G.vexnum>>G.arcnum;  		//输入图的顶点数和边数
 cout<<"请输入顶点信息:";
 for(int i=0;i<G.vexnum;i++){
  cin>>G.vexs[i];
 }
 for(int i=0;i<G.vexnum;i++){ 			//初始化邻接矩阵边权为无穷 
  for(int j=0;j<G.vexnum;j++){
   G.arcs[i][j]=MaxInt;
  }
 }
 VerTexType v1,v2;						//结点信息
 ArcType w;								//边权重
 cout<<"请输入边的两顶点及所构边的权重:"<<endl; 
 for(int i=0;i<G.arcnum;i++){		//利用二维数组寻址相对两点赋权
  cin>>v1>>v2>>w;    				//依次输入两个顶点以及所构边的权重
  G.arcs[VexLocate(G,v1)][VexLocate(G,v2)]=w;
  G.arcs[VexLocate(G,v2)][VexLocate(G,v1)]=w;
 }
 return OK;
}

Status VexInsert(AMGraph &G,VerTexType v){	//插入顶点
 G.vexs[G.vexnum]=v;     //由于数组下标比数量少1,可用旧顶点数做下标
 							  //增加新顶点 
 G.vexnum++;      		  //顶点数加1 
 for(int i=0;i<G.vexnum;i++){  //构建新顶点与其他顶点关联,初始化边权
 									 //为无穷 
  G.arcs[G.vexnum-1][i]=MaxInt;
  G.arcs[i][G.vexnum-1]=MaxInt;
 }
}

Status VexDelete(AMGraph &G,VerTexType v){	//顶点删除
 int p=VexLocate(G,v);					//存放待删顶点下标位置
 for(int i=0;i<G.vexnum;i++){			//删除待删顶点所在列数据
  for(int j=p+1;j<G.vexnum;j++){
   G.arcs[i][j-1]=G.arcs[i][j];
  }
 }
 for(int i=0;i<G.vexnum;i++){			//删除待删顶点所在行数据
  for(int j=p+1;j<G.vexnum;j++){
   G.arcs[j-1][i]=G.arcs[j][i];
  }
 }
 for(int i=p+1;i<G.vexnum;i++){		//删除在顶点集中的待删顶点
  G.vexs[i-1]=G.vexs[i];
 }
 G.vexnum--;							//顶点数自减
 return OK;
}

Status ArcInsert(AMGraph &G,VerTexType v1,VerTexType v2,ArcType w)
{ 												//插入边
 int p1=VexLocate(G,v1),p2=VexLocate(G,v2);	//存放两个关联点位置
 G.arcs[p1][p2]=w;						//将关联点在矩阵两处边权赋值
 G.arcs[p2][p1]=w;
 return OK;
}

Status ArcDelete(AMGraph &G,VerTexType v1,VerTexType v2){//删除边
 int p1=VexLocate(G,v1),p2=VexLocate(G,v2);	//存放两个关联点位置
 G.arcs[p1][p2]=MaxInt;			  //将关联点在矩阵两处边权赋为无穷
 G.arcs[p2][p1]=MaxInt;
 return OK; 
}

Status AMGraphPrint(AMGraph &G){	//打印无向邻接矩阵
 cout<<"邻接矩阵展示:"<<endl;
 for(int i=0;i<G.vexnum;i++){
  cout<<G.vexs[i]<<":";		  //输出矩阵行名
  for(int j=0;j<G.vexnum;j++){	  //循环输出各点与其他点的边权,0为无边
   if(G.arcs[i][j]!=MaxInt) cout<<G.arcs[i][j]<<"\t";
   else cout<<"0"<<"\t";
  }
  cout<<endl;
 }
 return OK;
}

int main(){
 AMGraph G;					//创建无向邻接矩阵
 UDNCreate(G);				//无向邻接矩阵初始化并存储数据
 AMGraphPrint(G);			//打印无向邻接矩阵
 VerTexType v1,v2;
 ArcType w;
 cout<<"请输入要插入的顶点:";
 cin>>v1;
 VexInsert(G,v1);			//插入顶点
 AMGraphPrint(G);			//打印无向邻接矩阵
 cout<<"请输入要删除的顶点:";
 cin>>v2;
 VexDelete(G,v2);			//删除顶点
 AMGraphPrint(G);			//打印无向邻接矩阵
 cout<<"请输入增加边的两个顶点及边权重:";
 cin>>v1>>v2>>w;
 ArcInsert(G,v1,v2,w);		//插入边
 AMGraphPrint(G);			//打印无向邻接矩阵
 cout<<"请输入删除边的两个顶点:";
 cin>>v1>>v2;
 ArcDelete(G,v1,v2);		//删除边
 AMGraphPrint(G);			//打印无向邻接矩阵
 return 0;
}

2、邻接表实现:

#include<iostream>
using namespace std;
typedef int Status;
#define OK 1
#define ERROR -1
#define VerTexType char
#define ArcType int
#define MVNum 50 

typedef struct ArcNode{    //边结点 
 int adjvex;     			//该边所指向的顶点位置
 struct ArcNode* nextarc;  //指向下一条边指针
 int weight;     			//边的权重 
};

typedef struct VNode{   	//顶点信息 
 VerTexType data;   		//顶点数据 
 ArcNode *firstarc;   		//指向第一条与该点相连的边的指针 
}VNode,AdjList[MVNum];   	//邻接表 

typedef struct{     		//定义图 
 AdjList vertices;   		//顶点表 
 int vexnum,arcnum;   		//图当前顶点数与边数 
}ALGraph;

int VexLocate(ALGraph &G,VerTexType v){  //顶点定位,找出其在邻接表
 												//中数组下标的位置 
 for(int i=0;i<G.vexnum;i++){
  if(v==G.vertices[i].data) return i;  //根据顶点数据查找,返回表中数
 											  //组下标值 
 }
 return -1;
}

Status ALGraphprint(ALGraph &G){    //邻接表打印函数 
 cout<<"操作后新的连接表如下:"<<endl;
 for(int i=0;i<G.vexnum;i++){    //依次输出每个顶点与相连顶点的情况
 									   //以及边权 
  cout<<G.vertices[i].data<<":";   	 //输出当前顶点数据 
  ArcNode* p=G.vertices[i].firstarc;  //指向与当前顶点相连的第一个顶
 											//点的边的指针 
  while(p!=NULL){       		//依次遍历所有与该顶点相连的点的边     
   cout<<G.vertices[p->adjvex].data<<"("<<p->weight<<")"<<"\t"; 
 									//输出与该顶点相连的所有点以及边的权重
   p=p->nextarc;
  }
  cout<<endl;
 }
 return OK;
}

Status Delete(ALGraph &G,int pos1,int pos2){ //删除邻接表中,指定两
 													//顶点的边 
 ArcNode* p=G.vertices[pos1].firstarc;  //指向pos1所表示顶点的与其
 											   //第一个相连顶点的边的指针
 if(p&&p->adjvex==pos2){      //由于firstarc指针固定,不能单纯删除p
 									//的结点,因此表头结点需要单独考虑 
  G.vertices[pos1].firstarc=p->nextarc; //如果表头结点存放连接信息为
 										  //要删结点位置信息pos2,直接删除
  delete p;
 }
 else{
  while(p!=NULL){       		//否则从p开始循环遍历表中所有连接点
   if(p->nextarc!=NULL&&p->nextarc->adjvex==pos2){  //如果找到要删
 											  //结点pos2,进行链表删除操作
    ArcNode* temp=p->nextarc;
    p->nextarc=p->nextarc->nextarc;
    delete temp;
    break;
   }
   p=p->nextarc;      			//没有找到,p指针后移 
  }
 }
 return OK;
}

Status UDGCreate(ALGraph &G){		//邻接表创建并存储数据
 cout<<"请输入图的总顶点数和总边数:";
 cin>>G.vexnum>>G.arcnum;
 cout<<"请输入顶点信息:";
 for(int i=0;i<G.vexnum;i++){    //初始化表头结点指针域为NULL 
  cin>>G.vertices[i].data;    	   //输入顶点数据 
  G.vertices[i].firstarc=NULL;
 }
 VerTexType v1,v2;
 ArcType w;
 int pos1,pos2;
 cout<<"请输入边的两顶点及所构边的权重:"<<endl;
 for(int i=0;i<G.arcnum;i++){    //输出边的信息 
  cin>>v1>>v2>>w;
  pos1=VexLocate(G,v1);     	   //获取顶点v1位置 
  pos2=VexLocate(G,v2);     	   //获取顶点v2位置 
  ArcNode* p1=new ArcNode;    	   //创建边结点 
  p1->adjvex=pos2;     		   //v1开始的边所连另一端为v2位置
  p1->weight=w;
  p1->nextarc=G.vertices[pos1].firstarc;  
  G.vertices[pos1].firstarc=p1;    //将边加入v1的边表头部
  ArcNode* p2=new ArcNode;     	 //创建边结点
  p2->adjvex=pos1;       			 //v2开始的边所连另一端为v1
  p2->weight=w;
  p2->nextarc=G.vertices[pos2].firstarc;
  G.vertices[pos2].firstarc=p2;    //将边加入v2的边表头部 
 }
 return OK; 
}

Status VexInsert(ALGraph &G,VerTexType v){  //实现顶点的插入 
 G.vertices[G.vexnum].data=v;    //由于数组下标从0开始,则新增顶点存
 									   //放位置为G.vexnum 
 G.vertices[G.vexnum].firstarc=NULL; //避免野指针情况,指针域为NULL 
 G.vexnum++;         			   //顶点数自增 
}

Status VexDelete(ALGraph &G,VerTexType v){  //顶点删除 
 int pos=VexLocate(G,v);      	//查找待删除顶点 
 for(int i=0;i<G.vexnum;i++){ //删除其他顶点连接表中的待删除顶点信息
  Delete(G,i,pos);
  
  //下半部份代码优化为Delete()函数 
//  ArcNode* p=G.vertices[i].firstarc;
//  if(p&&p->adjvex==pos){
//   G.vertices[i].firstarc=p->nextarc;
//   delete p;
//  }
//  else{
//   while(p!=NULL){
//    if(p->nextarc!=NULL&&p->nextarc->adjvex==pos){
//     ArcNode* temp=p->nextarc;
//     p->nextarc=p->nextarc->nextarc;
//     delete temp;
//     break;
//    }
//    p=p->nextarc;
//   }
//  }
 }
 
//下述操作:1、先删除待删顶点中所有连接表中其他顶点信息 2、用最后一个顶
//点替代删除结点位置(目的在于避免顶点表中出现废弃点占位情况)
 ArcNode* p=G.vertices[pos].firstarc;  //p指向待删顶点的第一个连接
 										   //点的边的指针 
 G.vertices[pos].firstarc=NULL;     //野指针问题,删除记得赋值为NULL,
 										  //否则运行无结果 
 while(p!=NULL){        //循环删除该点连接表下所有顶点信息 
  ArcNode* temp=p;
  p=p->nextarc;
  delete temp;
 }
 G.vertices[pos]=G.vertices[G.vexnum-1];  //将最后一个顶点替代删除
 												 //顶点的位置 
 G.vexnum--;         						 //顶点数自减 
 return OK; 
}

Status ArcInsert(ALGraph &G,VerTexType v1,VerTexType v2,int w){  
 												//插入边 
 int pos1,pos2;
 pos1=VexLocate(G,v1);
 pos2=VexLocate(G,v2);
 ArcNode* p1=new ArcNode;     //创建边结点 
 p1->adjvex=pos2;       		//v1开始的边所连另一端为v2位置 
 p1->weight=w;
 p1->nextarc=G.vertices[pos1].firstarc;  
 G.vertices[pos1].firstarc=p1;//将边加入v1的边表头部
 ArcNode* p2=new ArcNode;     //创建边结点
 p2->adjvex=pos1;       		//v2开始的边所连另一端为v1
 p2->weight=w;
 p2->nextarc=G.vertices[pos2].firstarc;
 G.vertices[pos2].firstarc=p2;    //将边加入v2的边表头部
 G.arcnum++;         			//边数自增 
 return OK;
}

Status ArcDelete(ALGraph &G,VerTexType v1,VerTexType v2){ //删除边
 int pos1,pos2;
 pos1=VexLocate(G,v1);      //存放删除边的第一个顶点位置 
 pos2=VexLocate(G,v2);      //存放删除边的第二个顶点位置 
 ArcNode* p1=G.vertices[pos1].firstarc;  //指向第一个顶点的连接表中
 												//与该顶点相连的边的指针 
 ArcNode* p2=G.vertices[pos2].firstarc;  //指向第二个顶点的连接表中
 												//与该顶点相连的边的指针
 Delete(G,pos1,pos2);      //在第一个顶点连接表中删除第二顶点的信息 
 Delete(G,pos2,pos1);      //在第二个顶点连接表中删除第一顶点的信息
 
 //下半部份代码用Delete()函数进行优化替代 
// if(p1&&p1->adjvex==pos2){
//  G.vertices[pos1].firstarc=p1->nextarc;
//  delete p1;
// }
// else{
//  while(p1!=NULL){
//   if(p1->nextarc!=NULL&&p1->nextarc->adjvex==pos2){
//    ArcNode* temp=p1->nextarc;
//    p1->nextarc=p1->nextarc->nextarc;
//    delete temp;
//    break;
//   }
//   p1=p1->nextarc;
//  }
// }
// if(p2&&p2->adjvex==pos1){
//  G.vertices[pos2].firstarc=p2->nextarc;
//  delete p2;
// }
// else{
//  while(p2!=NULL){
//   if(p2->nextarc!=NULL&&p2->nextarc->adjvex==pos1){
//    ArcNode* temp=p2->nextarc;
//    p2->nextarc=p2->nextarc->nextarc;
//    delete temp;
//    break;
//   }
//   p2=p2->nextarc;
//  }
// }
 G.arcnum--;				//边数自减
 return OK;
}



int main(){
 ALGraph G;
 UDGCreate(G);         	//构建图 
 ALGraphprint(G);         //打印图 
 VerTexType v1,v2;
 int w;
 cout<<"请输入要插入的顶点:";
 cin>>v1;
 VexInsert(G,v1);        //插入顶点 
 ALGraphprint(G);
 cout<<"请输入要删除的顶点:";
 cin>>v1;
 VexDelete(G,v1);        //删除顶点 
 ALGraphprint(G);
 cout<<"请输入要插入边的两顶点及边权重:";
 cin>>v1>>v2>>w;
 ArcInsert(G,v1,v2,w);   //插入边 
 ALGraphprint(G);
 cout<<"请输入要删除边的两顶点:";
 cin>>v1>>v2;
 ArcDelete(G,v1,v2);     //删除边 
 ALGraphprint(G);
 return 0;
}

四、结果展示

1、邻接矩阵结果:

【数据结构】图的基本操作

 2、邻接表结果:

【数据结构】图的基本操作

 五、算法时间复杂度

        1、邻接矩阵实现图的基本操作,函数包括:邻接矩阵创建并存储数据、顶点寻址、增加顶点、删除顶点、增加边、删除边、邻接矩阵打印。其中操作建立于二维数组,与数据规模有关,设总顶点数与总边数数据规模为n,则总体算法时间复杂度为O(n2)。

        2、邻接表实现图的基本操作,主要通过数组+链表方式进行数据处理。函数包括:邻接表创建并存储数据、顶点寻址、增加顶点、删除顶点、增加边、删除边、邻接表打印。其中操作主要建立于链表上,与数据规模有关,设总顶点数与总边数数据规模为n,则总体算法时间复杂为O(n)。

PS:第一次写博客,有问题欢迎交流。文章来源地址https://www.toymoban.com/news/detail-463094.html

到了这里,关于【数据结构】图的基本操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构--串的基本操作

    第五话 数据结构之串 文章目录 一、了解什么是串 二、串的基本特征 三、串的基本操作 串的初始化 串的输出  四、串的匹配模式 五、总结 串(即字符串)是一种特殊的线性表,在信息检索、文本编辑等领域有广泛的应用。其特殊性体现在组成线性表的每个数据元素是单个

    2023年04月17日
    浏览(55)
  • (数据结构)链队列的基本操作

    2024年02月08日
    浏览(44)
  • 数据结构之栈的基本操作

    该顺序栈涉及到了存储整型数据的顺序栈还有存储字符型数据的顺序栈 实现的功能有:入栈、出栈、判断是否为空栈、求栈的长度、清空栈、销毁栈、得到栈顶元素 此外根据上述功能,编写了数值转换(十进制转化八进制)方法、括号匹配方法。 控制台界面展示: 进栈展示

    2024年01月23日
    浏览(49)
  • 【数据结构】串的基本操作及应用

    分别定义两个结构体——串的定长顺序存储、串的堆式顺序存储   问题: 1、编写函数,串用定长顺序存储表示来实现串的基本操作; 2、 编写串的匹配算法,实现查找功能。 算法思想阐述: BF 算法:首先S[1] 和T[1] 比较,若相等,则再比较S[2] 和T[2] ,一直到T[M] 为止;若

    2023年04月26日
    浏览(43)
  • 【数据结构】串的基本定义及操作

    🌈积薪高于山,焉用先后别 🌈   🌟 正式开始学习数据结构啦~此专栏作为学习过程中的记录 🌟 概念熟记: 串 是由 0个或多个字符 组成的有限的序列,记作 S = ′ a 1 a 2 . . . a n ′ S=\\\'a_1a_2...a_n\\\' S = ′ a 1 ​ a 2 ​ ... a n ′ ​ ,其中,当 n = 0 n=0 n = 0 时表示空串 串 中任意多个

    2024年02月06日
    浏览(55)
  • 数据结构——单链表基本操作实现 (c++)

    单链表链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素(这里存储单元可以是连续的,也可以是不连续的),为了表示每个数据元素a与其直接后继数据元素之间的逻辑关系,除了存储信息本身外还要存储一个指示其直接后继的信息(地址). 这两部分信

    2024年02月03日
    浏览(68)
  • 数据结构---双向链表的基本操作

    头插法 遍历链表 尾插法 头删法 尾删法 按位置插入数据 按位置删除数据 dooublelinklist.c doublelinklist.h doublemain.c

    2024年02月22日
    浏览(53)
  • 【数据结构】单链表基本操作:查找、插入、删除、创建

     链表由结点组成,结点由数据域和指针域组成。其中,数据域存放的就是数据元素,指针域存放下一个结点的地址。数据元素可以只有一个,也可以有多个不同类型的数据元素,甚至是数组。下图和代码来自《C Primer Plus》,该链表每个节结点同时含char类型和int类型。 ​​

    2024年02月02日
    浏览(63)
  • 【数据结构】——单链表的基本操作(带头结点)

            单链表解决了顺序表需要大量连续存储单元的缺点,但单链表附加指针域, 存储密度较顺序表低(考点!!) 。由于单链表的元素离散地分布在存储空间中,所以单链表是 非随机存取 的存储结构,即不能直接找到表中某个特定的结点。当查找某个特定结点时,需要

    2024年02月05日
    浏览(51)
  • 数据结构——单链表上基本操作的实现

    1.按位序插入(带头结点) : ==ListInsert(L, i, e): ==在表L 中的第 i 个位置上插入指定元素 e = 找到第 i-1 个结点 ( 前驱结点 ) ,将新结点 插入其后;其中头结点可以看作第 0 个结点,故 i=1 时也适用。 typedef struct LNode{ ElemType data; struct LNode *next; }LNode, *LinkList; // 在第 i 个位置插入

    2024年01月21日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包