学习记录——顺序表(noj01-03)

T1:顺序表的插入运算

Q1:顺序表的创建 

step1. 类型定义         (12条消息) typedef介绍_liitdar的博客-CSDN博客

step2.创建线性表+初始化——元素设置默认值,长度设置为0 

        type1:

#include <stdio.h>
#include <stdlib.h>
#define MAXNUM 100;//最大存储个数
typedef struct//类型定义顺序表
{
    int element[MAXNUM];//存放数据元素
    int length;//当前长度
}SeqList;

SeqList CreatNullList(){
    SeqList L;//声明一个顺序表
    int i;
    for(i=0;i<MAXNUM;i++){
        L.element[i]=0;//将所有数据元素设置默认初始值;
//若不初始化顺序表,设置默认值,内存中将遗留脏数据。
    }
    L.length=0;//顺序表初始长度设置为0;
}//初始化顺序表
int main()
{
    SeqList L=CreatNullList();//初始化顺序表;
    ......
    return 0;
}

        type2:可变长 

#define SIZE 10
typedef struct List//定义一个不定长顺序表
{
    int *head;  //声明了一个名为head的长度不确定的数组,也叫“动态数组”
    int length; //当前表中元素个数
    int size;   //表的大小,类于MAXNUM;
}SqList,*PSeqList;

SqList InitList()//初始化
{
    SqList L;

    L.head = (int *)malloc(SIZE * sizeof(int));  //构造一个空的顺序表,动态申请存储空间
    
    if(!(L.head))   //如果申请失败,作出提示并直接退出程序
    {
        printf("初始化失败");
        exit(0);//ps.见下
    }

    L.size = SIZE; //空表的初始存储空间为SIZE
    L.length = 0;   //空表的长度初始化为0

    return L;
}
/*exit()是一个标准 C 库函数,包含在头文件<stdlib.h>里,是用来终止进程的,
        exit(0)表示程序正常退出,非0表示非正常退出。exit(1) 和exit(-1) 是分别返回1和-1到主调程序。
        return是语言级别的,它表示了调用堆栈的返回;exit是系统调用级别的,它表示了一个进程的结束。*/

Q2:顺序表的插入运算——按顺序插入元素x

引用1:在下标p处插入元素x

        思路:p位置元素及以后元素均向后移动一位,从后往前

        特况:     ①p非法:p<0|| ( p>palist->length)

                        ②移动后溢出:palist->length==MAXNUM

引用2:按值查找x的位置

#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define MaxSize 10
typedef struct
{
	int elem[MaxSize];
	int length;
}SeqList;
void InitList(SeqList* L){
    int i;
    for(i=0;i<MaxSize;i++){
        L->elem[i]=0;
    }
    L->length=0;
}
int insert_seq(SeqList* L,int i,int x)//在下标为i处插入元素x
{
        if(L->length==MaxSize){
            printf("Overflow!\n");
            return (ERROR);
        }
        if(i<0||(i>L->length)){
            printf("Not exist!\n");
            return (ERROR);
        }
        int p;
        for(p=L->length-1;p>=i;p--){
            L->elem[p+1]=L->elem[p];
        }
        L->elem[i]=x;
        L->length++;

        return (OK);
}
int locate_seq(SeqList* L,int x){
    int p=0;
    while(L->elem[p]<x){
        p++;
    }
    return p;
}

int main()
{
    SeqList L;
    SeqList* p;
    p=&L;
    InitList(p);

    scanf("%d",&L.length);
    int i;
    for(i=0;i<L.length;i++){
        scanf("%d",&L.elem[i]);
    }
    int x;
    scanf("%d",&x);

    i=locate_seq(p,x);
    insert_seq(p,i,x);
    for(i=0;i<L.length;i++){
        printf("%d ",L.elem[i]);
    }

    return 0;
}

T2:线性表的就地逆置

ps:noj BUG:可以用以下代码

#include<stdio.h>
int main()
{
    int n,i;
    int a[100];
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(i=n-1;i>=0;i--)
    {
        printf("%d ",a[i]);
    }
    printf("\n");
    for(i=n-1;i>=0;i--)
    {
        printf("%d ",a[i]);
    }
    return 0;
}

【W1】顺序表的就地逆置

易错点1:数组起始为0,末为n-1

易错点2:顺序表的建立

思考点1:顺序表的逆置

#include <stdio.h>
#include <stdlib.h>
#define MAXNUM 1000
typedef struct{
    int element[MAXNUM];
    int length;
}SeqList,*PSeqList;

void CreatNullSeqList(PSeqList p){
    int i;
    for(i=0;i<MAXNUM;i++){
        p->element[i]=0;
        p->length++;
    }
    p->length=0;
}
PSeqList inputSeqList(PSeqList p){
    scanf("%d",&p->length);
    int i;
    for(i=0;i<p->length;i++){
        scanf("%d",&p->element[i]);
    }
    return p;
}
PSeqList reverseSeqList(PSeqList p){
    int x,i,l=p->length;
    for(i=0;i<=(l/2);i++){
        x=p->element[i];
        p->element[i]=p->element[l-i-1];//注意开始元素下标为0,最后为n-

        p->element[l-i-1]=x;
    }
    return p;
}
void outputSeqList(PSeqList p){
    int i;
    for(i=0;i<p->length;i++){
        printf("%d ",p->element[i]);
    }
    printf("\n");
}


int main()
{
    SeqList L;
    PSeqList p=&L;//必需先定义一个L,再定义p

    CreatNullSeqList(p);
    inputSeqList(p);
    reverseSeqList(p);
    outputSeqList(p);

    return 0;
}

【W2】链表的就地逆置

Q1:链表的创建

参考文章:一口气搞懂「链表」,就靠这20+张图了 - 知乎 (zhihu.com)

step1:定义结点——数据域&指针域

step2:链表初始化——>创建头结点——>分配内存空间(注意需强制类型转换,malloc返回指向被分配内存的指针)&&初始化头结点: 

step3:建立链表(尾插法)

                        step3.1.1:已知 结点总数 n,

                        step3.1.2:创建过渡结点p(用于辅助记忆指向后继结点地址,类于尾结点)

                        step3.1.3:循环创建——创建结点s1、s2、......,

                                ①分配空间 ②输入数据 ③地址传递 ④地址移动 

typedef struct Node{//定义结点
    int data;
    struct Node* next;
}Node,*LinkList;
LinkList Creat_LinkList(){
    Node* head=(Node*)malloc(sizeof(Node));//创建头结点
    if(head==NULL){
        printf("Fail!");
        exit(0);
    }
    head->next=NULL;//Initial_LinkList

    Node* p;//中间过渡节点,相当于尾节点
	p=head;

	int n;//链表长度
	scanf("%d", &n);
	int i;
	for(i=0;i<n;i++)//循环创建结点,输入具体数据
	{
		Node* s=(Node*)malloc(sizeof(Node));
		scanf("%d", &s->data);
        p->next = s;
//因为插完第一个结点后用p保存了上一个结点,所以再插结点时应该插在p节点后面,这就是尾插。
        s->next = NULL;//别忘了让插在尾部的s结点的指针指向NULL。
        p = s;//p结点保存刚才的s结点;以保证p始终为链表的最后一个节点
	}
    free(p);
    return head;
}

Q2:就地逆置

参考文章:(13条消息) C语言 链表逆置四种方法 超详细_qascetic的博客-CSDN博客

思路: 

 链表逆置就地逆置法步骤解析图

 链表逆置就地逆置法步骤解析图

链表逆置就地逆置法步骤解析图

T3:顺序表的删除

#include <stdio.h>
#include <stdlib.h>
#define MAXNUM 100
#define FALSE 0
#define OK 1
typedef struct{
    int element[MAXNUM];
    int length;
}SeqList,*PSeqList;
void initializer_Seqlist(PSeqList p){
    p->length=0;
    int i;
    for(i=0;i<MAXNUM;i++){
        p->element[i]=0;
    }
}
int input_SeqList(PSeqList p,int l){
    p->length=l;
    if(l>=MAXNUM){
        printf("Overflow!");
        return FALSE;
    }
    int i;
    for(i=0;i<l;i++){
        scanf("%d",&p->element[i]);
    }
    return OK;
}
int delete_SeqList(PSeqList a,int x,int t){
    int i=t,m,n;
    while(a->element[i]!=x&&i<a->length) i++;
    if(i==a->length){
        return t;
    }
    t=i;
    i=a->length-1;
    for(m=a->element[i];i>t;i--){
        n=a->element[i-1];
        a->element[i-1]=m;
        m=n;
    }
    a->length--;
    return t;
}
void fun_sameBC(PSeqList b,PSeqList c,PSeqList a){
    int i=0,j=0,t=0;
    int x,y;
    while(i<b->length&&j<c->length){
        x=b->element[i];
        y=c->element[j];
        if(x>y){
            j++;
        }
        if(x==y){
            i++;
            j++;
            t=delete_SeqList(a,x,t);
        }
        if(x<y){
            i++;
        }
    }
}
int output_Seqlist(PSeqList a){
    int i=0;
    int l=a->length;
    if(!l){
        printf("NULL!");
        return FALSE;
    }
    for(i=0;i<l;i++){
        printf("%d ",a->element[i]);
    }
    return OK;
}
int main()
{
    int m,n,p;
    scanf("%d %d %d",&m,&n,&p);
    SeqList A,B,C;
    PSeqList a=&A,b=&B,c=&C;
    initializer_Seqlist(a);
    initializer_Seqlist(b);
    initializer_Seqlist(c);
    input_SeqList(a,m);
    input_SeqList(b,n);
    input_SeqList(c,p);
    fun_sameBC(b,c,a);
    output_Seqlist(a);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值