这几天练习了下线性表的逆置,顺序表比较简单,就是数组的位置交换。
-
顺序表的逆置
-
单链表的逆置
-
头插法
-
就地逆置
-
递归
顺序表的逆置:
中间变量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指向的结点发生改变。
过程如下:
链表的部分基本操作包含在第一个完整代码中。