线性表:顺序表,链表常见基本运算操作大全(基础才是硬道理)

顺序表

走过路过不要错过的啦!

顺序表的6个基本运算

1:顺序表初始化运算的实现

void initialList(seqList *L)
{

    //由于所需要的连续储存空间在代码编译时候已经确定,只需要把长度设为0
    L->listLen = 0;

}

2:求表长度函数的实现

​
​
int listLengt(seqList L){//返回类型为int

    return L.listLen;
}

​

​

3:按序号求元素的实现

​
void getElement(seqlist L,int i ,elementType * x){

    if(i <1 || i > L.listLen){
      //自定义实现报错信息
    }else{
      *x = L.data[i-1];
    }

}

​

4:查找元素的实现

int listLocate(seqList L,elementType x){
    int i ;
    for(i = 0 ;i< L.listLen ;i++){
         if(L.data[i] = x;
        return i + 1;
    }
    
    return 0;//表示未查找的元素
}

5:插入算法的实现

int listInsert(serList* L, elementType x, int i) {
	int j;
	if (L->listLen == MAXLEN) {
		return 0;//表示表满,无法插入新的元素
	}
	else if (i < 1 || i > L->listLen + 1) {
		return -1 //表示超出范围
	}
	else {
		for (j = L->listLen; j >= i; j--) {//将将要插入的位置后面的信息单元依次后移一个单元
			L->data[j] = L->data[j + 1];
		}
		L->data[i] = x;
		L->listLen++;
		return 1//表示成功
	}

6:删除算法的实现


int listDelet(seqList *L, int i){
	int j;
	if (L->listLen == 0) {
		return 0;//表示空表
	}
	else if (i < 1 || i > L->listLen + 1) {
		return -1;//表示索引范围越界
	}
	else {
		for (j = i ; j < L->listLen; j++)
		{
			L->data[j-1] = L->data[j];
		}
		L->listLen--;
		return 1;//表示删除成功
	}
}

无序顺序表的交并差

1:交

//求C=A∩B
void interSet(List A, List B, List &C)
{
int i;
for(i=0;i<A.listLen;i++)//遍历A集合
{
		if(listLocate(B,A.data[i])!=0){//判断A.data[i]是否在B中出现
		listInsert(&C,A.data[i],C.listLen+1);//插入交叉元素
}
	}
}

2:并

//求C=A∪B
void mergeSet(List A, List B, List &C)
{
   int i;
	for(i=0;i<A.listLen;i++) //先把A中元素全部插入到C中 
	{
	  listInsert(&C,A.data[i],C.listLen+1);
    }
    for(i=0;i<B.listLen;i++)//再插入B中除去A中所含的元素
    {
	   if(listLocate(A,B.data[i])==0) 
         {
	      listInsert(&C,B.data[i],C.listLen+1);
         }
    }
}

3:差

//求C=A-B
void differentSet(List A,List B,List &C)
{
    int i;
    for(i=0;i<A.listLen;i++)
    {
	     if(listLocate(B,A.data[i])==0) //插入A中B所没有的元素
        {
	      listInsert(&C,A.data[i],C.listLen+1);
        } 
    }
}

有序顺序表的两个例子

1:设计算法A= A∩B

void InterSet(List &A, List &B)
{
    int i= 0;    //为了最后更新交集元素表长度操作一致,初始化为-1i
    int a=0, b=0;    //A、B表当前元素的数组下标
    while(a<A.listLen && b<B.listLen)
    {	
        if(A.data[a]==B.data[b])    //a和b指示的是交集元素
        {	
            if(a!=i)//a元素复制到i+1,否则a位置即目标位置,不需复制元素
            {
                A.data[i]=A.data[a];
	            i++;
                a++;
                b++;
            }
        else if(A.data[a]<B.data[b])  {   //以下为非交集元素处理
            a++;
        } 
        else{
             b++;
        }
   
    }
    A.listLen=i;    //更新A表长度,使等于交集元素个数
}

2:设计算法A=A-B

​
​
void Set (List & A, List & B)
{	
    int i=0;    //指示A中已经处理的最后元素
    int a=0, b=0;   //初始化A,B位
    while( a<A.listLen && b<B.listLen )
    {
        if(A.data[a]==B.data[b])      //当a,b相同时,a、b同时后移
        {
            a++;
            b++;
        }
        else if(A.data[a]>B.data[b]){
            b++;
        }      //此时,a指示元素排在b指示的元素后面,移动b。
        else    
        {        //所以a指示元素必在A-B中。//如果(i+1)==a,说明a元素不需迁移位置,直接为A-B中元素
             if(i!=a)  
             {
                A.data[i]=A.data[a];
             }
            i++;    //A-B集合最后元素指示后移
            a++; //A的指示后移
        }
     }
    //处理B结束,A未结束情况,A中剩下部分元素全部为所差元素
    while(a<A.listLen)   
    {
        if(i!=a){
        A.data[i]=A.data[a];
        }
        i++;    //A-B集合最后元素指示器后移
        a++; //A的指示器后移
    }
    A.listLen=i + 1;    //更新表A的长度
}

​

​

链表:

链表基本运算的实现

1:初始化链表运算的实现

void intialList(node * &L)//这里使用引用的方式回传初始化链表
{
    L = new node;//申请头结点
    L->next = null;//头结点后继指针为null

}

2:求链表长度

int listLength(node *L)
{
  int len = 0;//设置计数器
  node * p = L->next;//p初始化指向首元素地址
  while(p != null)
  {
    len++;
    p = p->next; //p移到下一个结点,继续后续节点的奇数
    
    
  } 
    return len;//返回结果
}

3:按序号取元素结点的实现

​
node * getElement(node *L, int i)
{
   //可以在此之前对i进行检查,此处省去
   
   node* p = L->next;//p指向第一个元素地址
   int j = 1;//设置计数器
   while(p != null && j != i)
   {
          j++;     
      p = p->next;
   }
   
    return p;
}

​

4:按值查询元素

node* listLocate(node* L, elementType x) 
{
	node* p = L->next;//指向首元素地址
	
	while (p != null && p->data != x) {
		p = p->next;//p不是目标结点,继续搜索下一个结点
	}

	return p;
}

5:插入算法的实现

bool listInset(node* L ,int i,elementType x)
{
	node * p = L;//p指向头结点
	node* S;
	int k = 0;//设置计数器
	while(k != i - 1 && p != null)
	{
		p = p->next;//p指向下一个结点
		k++;//计数器加一
	}

	if (p == NULL)
	{
		return false;//说明插入位置无效
	}
	else
	{
		S = new node;
		S->data = x;//装入数据
		S->next = p->next;//改变逻辑结构
		p->next = S;

		return true;//返回true表示插入完成
	}

}

6:删除算法的实现

​
bool listDelete(node* L , int i)
{
	node* temp;
	node* p = L;//指向头结点,之所以不指向首元素是因为可能要删除首元素
	int k = 0;//设置计数器

	while (k != i && p->next != null)//删除,需要该节点的上一个结点p,因此结点p后继结点必须要存在,p不是尾结点
	{
		p = p->next;
		k++;
	}
	if (p->next == NUll)
	{
		return false;
	}
	else
	{
		/*
		这样不容易释放原先p之后的结点元素地址
		temp = p->next->next;
		p->next = temp;*/
		
		temp = p->next;
		p->next = temp->next;
		delete temp;
		return true;
		
	}

}

​

有问题欢迎指正!

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲码的小陈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值