线性表逆置(顺序表和单链表)

这几天练习了下线性表的逆置,顺序表比较简单,就是数组的位置交换。

  1. 顺序表的逆置

  2. 单链表的逆置

  3. 头插法

  4. 就地逆置

  5. 递归

顺序表的逆置:
中间变量temp,交换首位两个元素的位置。

void ListReverse(Sqlist &l){
 int i;
 Elemtype temp;
 for(i=0;i<l.length/2;i++){
  temp=l.elem[i];
  l.elem[i]=l.elem[l.length-i-1];
  l.elem[l.length-i-1]=temp;
 }
}

完整代码如下:

#define TRUE 1
#define FALSE 0
#define ERROR -1
#define OVERFLOW -1
#define INFEASIBLE -1
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int Status;
typedef int Elemtype;
typedef struct{
 Elemtype *elem;
 int length;
 int listsize;
}Sqlist;
Status ListInit(Sqlist &l){
 l.elem=(Elemtype *)malloc((LIST_INIT_SIZE)*sizeof(Elemtype));
 if(!l.elem) exit(OVERFLOW); 
 l.length=0;
 l.listsize=LIST_INIT_SIZE;
 return TRUE;
}
Status ListPrint(Sqlist l){
 for(int i=0;i<l.length;i++){
  cout<<l.elem[i]<<" ";
 }
}
Status ListInsert(Sqlist &l, int pos, Elemtype e){
 if(pos<1||pos>l.length+1) return ERROR;
 if(l.length>=l.listsize){
  Elemtype *base=(Elemtype *)realloc(l.elem,(LIST_INIT_SIZE+LISTINCREMENT)*sizeof(Elemtype));//给数组扩容 
  if(!base) return ERROR;
  l.elem=base;
  l.listsize+=LISTINCREMENT;//仅仅只是容量扩大,长度还未发生改变 
 }
 Elemtype *p=&(l.elem[pos-1]);
 Elemtype *q=&(l.elem[l.length-1]);
 for(;q>=p;q--){
  *(q+1)=*q;
 }
 *p=e;
 l.length++;
 return TRUE;
}
void ListReverse(Sqlist &l){
 int i;
 Elemtype temp;
 for(i=0;i<l.length/2;i++){
  temp=l.elem[i];
  l.elem[i]=l.elem[l.length-i-1];
  l.elem[l.length-i-1]=temp;
 }
}
int main(){
 Elemtype e, num;
 int m,k,p;
 Sqlist la;
 ListInit(la);
 cout<<"请输入la的元素个数:"<<endl;
 cin>>m;
 for(int i=0;i<m;i++){
  cin>>e;
  ListInsert(la,i+1,e);
 }
 ListReverse(la);
 ListPrint(la);
}

运行结果如下:
在这里插入图片描述
单链表的逆置:

  • 头插法:
    void Reverse(LinkList &l){//头结点未变 LinkList p,q; p=l->next; l->next=NULL; while(p!=NULL){ q=p; p=p->next; q->next=l->next; l->next=q; } }
    过程如下:
    在这里插入图片描述
    }
    原来链表中的头结点最终会指向尾元结点,所以头结点不变。
  • 就地逆置
LinkList Reverselinklist(LinkList &l){
 LinkList pCur=l->next,pRev, pTemp;
 pRev=NULL;
 if(l==NULL||l->next==NULL) return l;
 while(pCur!=NULL){  
  pTemp=pCur;
  pCur=pCur->next;
  pTemp->next=pRev;
  pRev=pTemp;
 }
 LinkList newH=(LinkList)malloc(sizeof(LNode));
 newH->next=pRev;
 return newH;
}

就地逆置最终pRev指向原来链表的尾元结点,需要新建一个头结点指向pRev,否则该单链表是无头结点的。
过程如下:
在这里插入图片描述

  • 递归
LinkList RecursionReverse(LinkList &l){
 if(l==NULL||l->next==NULL) return l;
 LinkList newH=RecursionReverse(l->next);
 l->next->next=l;
 l->next=NULL;
 return newH;
}

递归是从最后一个结点开始之前的结点逐个返回,但是需要将每一次返回的l->next设置成NULL,否则下一次递归会使l->next->next指向的结点发生改变。
过程如下:
在这里插入图片描述
链表的部分基本操作包含在第一个完整代码中。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值