王道代码刷题记录

文章目录

  • 1.设计一个递归算法,删除不带头节点的单链表L所有值为x的节点
  • 2.在带头节点的单链表L中,删除所有值为x的节点,并释放其空间,假设值为x的节点不唯一,试着编写以下算法以实现这个操作。
  • 3. 设L为带头节点的单链表,编写算法实现从尾到头反向输出节点
  • 4.试编写带头节点的单链表L 删除一个最小值节点的高效算法
  • 5. 试编写算法将带头结点的单链表就地逆置,所谓就地是指辅助空间复杂度为O(1)
    • 设在一个带表头结点的单链表中所有元素结点的数据值无序,试编写一个函数,删除表中所有介于给定两个值(作为函数参数给出)之间元素的元素(若存在)

1.设计一个递归算法,删除不带头节点的单链表L所有值为x的节点

//设计一个递归算法,删除不带头节点的单链表L所有值为x的节点
//递归出口:L->next==NULL
#include 
#include 
using namespace std;
typedef struct node{
     
	int data;
	struct node *next;//定义指向后继节点的指针
}node,*Linklist;
void createList(Linklist &L,int n){
     
	node *p;
    Linklist q=(Linklist)malloc(sizeof(node));//建立一个新节点
    q=L;
	for(int i=0;i<n;i++){
     
        p=(Linklist)malloc(sizeof(node));
        printf("请输入第%d个节点",i+1);
		scanf("%d",&p->data);
        if(L==NULL){
     
            L=p;
        }else{
     
            q->next=p;
            q=q->next;
        }
	}
}
void deletex(Linklist &L,int n){
     
    node *q;//指向待删节点
    if(L==NULL){
     
        return;
    }
    if(L->data==n){
     
        q=L;//删除当前L的节点
        L=L->next;
        free(q);
        deletex(L,n);
    }
    else{
     
        deletex(L->next,n);//看这个else里的函数,L不是待删除节点时,调用L->next,这样到达递归出口后,按层返回,L剩下的就都是非x的节点
    }
}
void printlist(Linklist L){
     
    while(L!=NULL){
     
        printf("%d",L->data);
        L=L->next;
    }
}
int main(){
     
    Linklist L=(Linklist)malloc(sizeof(node));
    createList(L,3);
    //删除值为3的节点
    //定义一个遍历的指针p
    deletex(L,3);
    printlist(L);
    cout<<endl;
}

2.在带头节点的单链表L中,删除所有值为x的节点,并释放其空间,假设值为x的节点不唯一,试着编写以下算法以实现这个操作。

//在带头节点的单链表L中,删除所有值为x的节点,并释放其空间,假设值为x的节点不唯一,试着编写以下算法以实现这个操作。
#include 
#include 
using namespace std;
typedef struct node{
     
	int data;
	struct node *next;//定义指向后继节点的指针
}node,*Linklist;
void createList(Linklist &L,int n)
{
     
	L=(Linklist)malloc(sizeof(node));
    node *q;//指向尾节点
    q=(Linklist)malloc(sizeof(node));
    node *p;//指向新建节点
    q=L;
	for(int i=0;i<n;i++){
     
		p=(Linklist)malloc(sizeof(node));//建立一个新节点
        printf("请输入第%d个节点",i+1);
		scanf("%d",&p->data);
		q->next=p;
        q=q->next;
	}
}

void deletex(Linklist &L,int x){
     
    node *q;//前指针
    q=(Linklist)malloc(sizeof(node));
    q=L;
    node *p;//后指针
    while(q->next!=NULL){
     
        p=(Linklist)malloc(sizeof(node));
        if(q->next->data==x){
     
            p=q->next;
            q->next=p->next;
            free(p);
        }else{
     
            q=q->next;
        }
    }
}
void printlist(Linklist L){
     
    while(L->next!=NULL){
     
        printf("%d",L->next->data);
        L=L->next;
    }
}
int main(){
     
    Linklist L;
    createList(L,3);
    deletex(L,3);
    printlist(L);
    cout<<endl;
}

3. 设L为带头节点的单链表,编写算法实现从尾到头反向输出节点

#include 
#include 
using namespace std;
typedef struct node{
     
    int data;
    node *next;
}node,*Linklist;
void CreateList(Linklist &L,int n){
     
    //尾插法
    node *q;
    q=(Linklist)malloc(sizeof(node));
    q=L;//q指向前一个节点
    node *p;//p指向待插节点;
    for(int i=0;i<n;i++){
     
        p=(Linklist)malloc(sizeof(node));
        printf("请输入第%d个节点",i+1);
        scanf("%d",&p->data);
        q->next=p;
        q=q->next;
    }
}
void PrintList(Linklist L)
{
     
    while(L->next!=NULL){
     
        printf("%d",L->next->data);
        L=L->next;
    }
}
void backprint(Linklist L){
     
    if(L->next==NULL){
     
        return;
    }else{
     
        backprint(L->next);
        printf("%d",L->next->data);
        //返回到上一个L输出L->next->data;
    }
}
int main()
{
     
    Linklist L=(Linklist)malloc(sizeof(node));
    CreateList(L,4);
    backprint(L);
    return 0;
}

4.试编写带头节点的单链表L 删除一个最小值节点的高效算法

懒的删结点了,只找了最小值。记录一下盲点:
用while遍历带头结点的链表时,设一个指针p指向L,遍历的时候只需要判断p->next是否为空。

//试编写带头节点的单链表L 删除一个最小值节点的高效算法
//1.找到最小值,设置一个中间指针m指向当前最小节点
#include 
#include 
using namespace std;
typedef struct node{
     
    int data;
    node *next;
}node,*Linklist;
void Createlist(Linklist &L,int n){
     
    node *q;
    q=(Linklist)malloc(sizeof(node));
    q=L;
    node *p;
    for(int i=0;i<n;i++){
     
        p=(Linklist)malloc(sizeof(node));
        printf("请输入第%d个数字",i+1);
        scanf("%d",&p->data);
        q->next=p;
        q=q->next;
    }
}
void PrintList(Linklist L)
{
     
    while(L->next!=NULL){
     
        printf("%d",L->next->data);
        L=L->next;
    }
}
void minnum(Linklist L){
     
    node *p;
    node *min;
    p=(Linklist)malloc(sizeof(node));
    min=(Linklist)malloc(sizeof(node));
    p=L;
    min=L->next;
    printf("输出");
    while(p->next){
     
        if(p->next->data<min->data){
     
            min=p->next;
        }
        p=p->next;
    }
    printf("%d",min->data);
}
int main()
{
     
    Linklist L;
    L=(Linklist)malloc(sizeof(node));
    Createlist(L,5);
    PrintList(L);
    minnum(L);
    //free(L);
    return 0;
}


找到一个比王道答案更好的算法。这样只需要删除min->next的指针就可以了,不用再多设前驱指针。

void minnum(Linklist L){
     
    node *p;
    node *min;
    p=(Linklist)malloc(sizeof(node));
    min=(Linklist)malloc(sizeof(node));
    p=L;
    min=L;
    printf("输出");
    while(p->next){
     
        if(p->next->data<min->next->data){
     
            min=p;
        }
        p=p->next;
    }
    printf("%d",min->next->data);
}

5. 试编写算法将带头结点的单链表就地逆置,所谓就地是指辅助空间复杂度为O(1)

//试编写算法将带头结点的单链表就地逆置,所谓就地是指辅助空间复杂度为O(1)
//方法一:用头插法
#include 
#include 
using namespace std;
typedef struct node{
     
    int data;
    node *next;
}node,*Linklist;
void Createlist(Linklist &L,int n){
     
    node *q;
    q=(Linklist)malloc(sizeof(node));
    q=L;
    node *p;
    for(int i=0;i<n;i++){
     
        p=(Linklist)malloc(sizeof(node));
        printf("请输入第%d个数字",i+1);
        scanf("%d",&p->data);
        q->next=p;
        q=q->next;
    }
}
void PrintList(Linklist L)
{
     
    while(L->next!=NULL){
     
        printf("%d",L->next->data);
        L=L->next;
    }
}
void reverse(Linklist &L){
     
    //头插法
    	node *p = L->next;
        //p=(node*)malloc(sizeof(node));
	    L->next = NULL;//让L断链,使L成为新结点
	    while(p){
     
		    node *q = p->next;
            //q=(Linklist)malloc(sizeof(node));
		    p->next =  L->next;
		    L->next = p;
		    p = q;
	    }

}
int main()
{
     
    Linklist L,Ls;
    L=(Linklist)malloc(sizeof(node));
    Ls=(Linklist)malloc(sizeof(node));
    Createlist(L,5);
    reverse(L);
    PrintList(L);
    return 0;
}

设在一个带表头结点的单链表中所有元素结点的数据值无序,试编写一个函数,删除表中所有介于给定两个值(作为函数参数给出)之间元素的元素(若存在)

#include 
#include 
using namespace std;
typedef struct node{
     
    int data;
    node *next;
}node,*Linklist;
void Createlist(Linklist &L,int n){
     
    node *q;
    q=(Linklist)malloc(sizeof(node));
    q=L;
    node *p;
    for(int i=0;i<n;i++){
     
        p=(Linklist)malloc(sizeof(node));
        printf("请输入第%d个数字",i+1);
        scanf("%d",&p->data);
        q->next=p;
        q=q->next;
    }
    q->next=NULL;
}
void PrintList(Linklist L)
{
     
    while(L->next!=NULL){
     
        printf("%d",L->next->data);
        L=L->next;
    }
}
void deletebt(Linklist &L,int a,int b){
     
    node *pre = L;
	while(pre->next){
     
		node *q = pre->next;
        q=(Linklist)malloc(sizeof(node));
		if(q->data>a&&q->data<b){
     
			pre->next=q->next;
            free(q);
		}
        pre=pre->next;
	}

}
int main()
{
     
    Linklist L;
    L=(Linklist)malloc(sizeof(node));
    //Ls=(Linklist)malloc(sizeof(node));
    Createlist(L,5);
    deletebt(L,2,5);
    PrintList(L);
    return 0;
}

你可能感兴趣的:(数据结构)