【数据结构C语言实现】线性表

一、从数据结构的三要素了解线性表

1、逻辑结构

定义:线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列
特点:除第一个元素外,每个元素有且仅有一个直接前趋,除最后一个元素外,每个元素有且仅有一个直接后继
线性表是一种逻辑结构

2、数据的运算

数据的运算即是对数据结构的操作集
以下通过抽象数据类型描述体现线性表

抽象数据类型描述

(参考中国大学mooc浙江大学数据结构)
在这里插入图片描述

3、存储结构

顺序表——顺序存储实现

数据结构与算法题目集(中文)6-2

#include<stdio.h>
#include<stdlib.h>

#define MAXSIZE 5
#define ERROR -1
typedef enum {false, true} bool;
typedef int ElementType;
typedef int Position;
typedef struct LNode *List;//定义一个指向结构体struct LNode的指针变量 
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last;//表示最后一个元素 
};

/* 初始化 */
List MakeEmpty()
{
    List L;

    L = (List)malloc(sizeof(struct LNode));//将该内存空间首地址转换为list结构体指针类型 
    L->Last = -1;//->相当于java中某个方法中引用成员变量 即L.last

    return L;
}

/* 查找 */
Position Find( List L, ElementType X )
{
    Position i = 0;

    while( i <= L->Last && L->Data[i]!= X )
        i++;
    if ( i > L->Last )  return ERROR; /* 如果没找到,返回错误信息 */
    else  return i;  /* 找到后返回的是存储位置 */
}

/* 插入 */
/*注意:在插入位置参数P上与课程视频有所不同,课程视频中i是序列位序(从1开始),这里P是存储下标位置(从0开始),两者差1*/
bool Insert( List L, ElementType X, Position P ) 
{ /* 在L的指定位置P前插入一个新元素X */
    Position i;

    if ( L->Last == MAXSIZE-1) {
        /* 表空间已满,不能插入 */
        printf("表满"); 
        return false; 
    }  
    if ( P<0 || P>L->Last+1 ) { /* 检查插入位置的合法性 */
        printf("位置不合法");
        return false; 
    } 
    for( i=L->Last; i>=P; i-- )//从最后一个元素往前 ,如果是从前往后挪,后面的元素会被前一个元素覆盖 
        L->Data[i+1] = L->Data[i]; /* 将位置P及以后的元素顺序向后移动 */
    L->Data[P] = X;  /* 新元素插入 */
    L->Last++;       /* Last仍指向最后元素 */
    return true; 
} 

/* 删除 */
/*注意:在删除位置参数P上与课程视频有所不同,课程视频中i是序列位序(从1开始),这里P是存储下标位置(从0开始),两者差1*/
bool Delete( List L, Position P )
{ /* 从L中删除指定位置P的元素 */
    Position i;

    if( P<0 || P>L->Last ) { /* 检查空表及删除位置的合法性 */
        printf("位置%d不存在元素", P ); 
        return false; 
    }
    for( i=P+1; i<=L->Last; i++ )
        L->Data[i-1] = L->Data[i]; /* 将位置P+1及以后的元素顺序向前移动 */
    L->Last--; /* Last仍指向最后元素 */
    return true;   
}

int main()
{
    List L;
    ElementType X;
    Position P;
    int N;

    L = MakeEmpty();//初始化顺序表 
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        if ( Insert(L, X, 0)==false )
            printf(" Insertion Error: %d is not in.\n", X);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else
            printf("%d is at position %d.\n", X, P);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &P);
        if ( Delete(L, P)==false )
            printf(" Deletion Error.\n");
        if ( Insert(L, 0, P)==false )
            printf(" Insertion Error: 0 is not in.\n");
    }
 
    return 0; 
}

输入样例:
6
1 2 3 4 5 6
3
6 5 1
2
-1 6

输出结果:
在这里插入图片描述

链表——链式存储实现

不带头结点的链式表操作集

题源:PTA 数据结构与算法题目集(中文)6-5

#include<stdio.h>
#include<stdlib.h>

#define ERROR NULL 
typedef int ElementType;
typedef struct LNode *PtrTolNode;
struct LNode{
	ElementType Data;
	PtrTolNode Next;//指向下一个 
};
typedef PtrTolNode Position;
typedef PtrTolNode List;

//查找值为X的元素 (返回线性表中首次出现X的位置,若找不到则返回ERROR)
Position Find(List L,ElementType X){
	Position p=L;//p指向L的第一个结点
	while(p&&p->Data!=X){
		p=p->Next;
	}
	if(p){
		return p;
	}else{
		return ERROR;
	}
}

/*
 *不带头结点的插入 
 *将X插入在位置P指向的结点之前,返回链表的表头
 *如果参数P指向非法位置,则打印"Wrong Position for Insertion" 返回ERROR
 */ 
List Insert(List L,ElementType X,Position P){
	if(P==L){
		List Node = (List)malloc(sizeof(List));
		Node->Data=X;
		Node->Next=L;
		return Node;
	}
	Position pre,tmp;
	//查找P的前驱 
	for(pre=L;pre&&pre->Next!=P;pre=pre->Next);
	if(pre==NULL){//P所指结点不在L中 
		printf("Wrong Position for Insertion\n");
		return ERROR;
	}else{//找到了P所指结点前驱
		tmp=(Position)malloc(sizeof(struct LNode));//申请、填装结点 
		tmp->Data=X;
		/*
		修改前: 
		tmp->Next=pre->Next;
		pre->Next=tmp->Next;*/
		//修改后 
		tmp->Next = P;
        pre->Next = tmp;
		return L;
	}
} 
/*
不带头结点的删除 
将X插入在位置P指向的结点之前,返回链表的表头
若参数P指向非法位置,则打印"Wrong Position for Deletion"并返回ERROR 
*/ 
List Delete(List L,Position P){
	if(P==L){
		L=L->Next;
		return L;
	}
	Position pre;
	//查找表中P指向结点的前驱
	for(pre=L;pre&&pre->Next!=P;pre=pre->Next);
	if(pre==NULL){
		printf("Wrong Position for Deletion\n");
		return ERROR;
	}else{
		pre->Next=P->Next;
		free(P);
		return L;
	}
}

int main()
{
    List L;
    ElementType X;
    Position P, tmp;
    int N;

    L = NULL;
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        L = Insert(L, X, L);
        if ( L==ERROR ) printf("Wrong Answer\n");
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else {
            L = Delete(L, P);
            printf("%d is found and deleted.\n", X);
            if ( L==ERROR )
                printf("Wrong Answer or Empty List.\n");
        }
    }
    L = Insert(L, X, NULL);
    if ( L==ERROR ) printf("Wrong Answer\n");
    else
        printf("%d is inserted as the last element.\n", X);
    P = (Position)malloc(sizeof(struct LNode));
    tmp = Insert(L, X, P);
    if ( tmp!=ERROR ) printf("Wrong Answer\n");
    tmp = Delete(L, P);
    if ( tmp!=ERROR ) printf("Wrong Answer\n");
    for ( P=L; P; P = P->Next ) printf("%d ", P->Data);
    return 0;
}

输入样例:

6
12 2 4 87 10 2
4
2 12 87 5

结果:

2 is found and deleted.
12 is found and deleted.
87 is found and deleted.
Finding Error: 5 is not in.
5 is inserted as the last element.
Wrong Position for Insertion
Wrong Position for Deletion
10 4 2 5 
带头结点的链式表操作集

题源:PTA数据结构与算法题目集(中文)6-6

#include <stdio.h>
#include <stdlib.h>

#define ERROR NULL
typedef enum {false, true} bool;
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

List MakeEmpty(){
/*
创建并返回一个空的线性表;
*/
	List L;
	L=(List)malloc(sizeof(struct LNode));
	L->Next=NULL;
	return L;
}

Position Find( List L, ElementType X ){
/*
返回线性表中X的位置。若找不到则返回ERROR
*/	
	Position p=L->Next;//第一个结点 
	while(p!=NULL){
		if(p->Data==X) return p;
		p=p->Next;
	}
	return ERROR;
}

bool Insert( List L, ElementType X, Position P ){
/*
将X插入在位置P指向的结点之前,返回true。
如果参数P指向非法位置,则打印“Wrong Position for Insertion”,返回false
*/
	Position tmp,pre;
	for(pre=L;pre&&pre->Next!=P;pre=pre->Next);//找p的前驱
	if(pre==NULL){
		printf("Wrong Position for Insertion\n");
		return false;
	} 
	else{
		tmp=(Position)malloc(sizeof(struct LNode));//分配新的空间给新的结点
		tmp->Data=X;
		tmp->Next=P;
		pre->Next=tmp;
		return true; 
	}
}


bool Delete( List L, Position P ){
/*
将位置P的元素删除并返回true。
若参数P指向非法位置,则打印“Wrong Position for Deletion”并返回false。
*/ 
	Position pre;
	for(pre=L;pre&&pre->Next!=P;pre=pre->Next);//找p的前驱
	if(pre==NULL){
		printf("Wrong Position for Deletion\n");
		return false;
	}
	else{
		pre->Next=P->Next;
		free(P);//释放结点P的空间 
		return true;
	}
}

int main()
{
    List L;
    ElementType X;
    Position P;
    int N;
    bool flag;

    L = MakeEmpty();
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        flag = Insert(L, X, L->Next);
        if ( flag==false ) printf("Wrong Answer\n");
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else {
            flag = Delete(L, P);
            printf("%d is found and deleted.\n", X);
            if ( flag==false )
                printf("Wrong Answer.\n");
        }
    }
    flag = Insert(L, X, NULL);
    if ( flag==false ) printf("Wrong Answer\n");
    else
        printf("%d is inserted as the last element.\n", X);
    P = (Position)malloc(sizeof(struct LNode));
    flag = Insert(L, X, P);
    if ( flag==true ) printf("Wrong Answer\n");
    flag = Delete(L, P);
    if ( flag==true ) printf("Wrong Answer\n");
    for ( P=L->Next; P; P = P->Next ) printf("%d ", P->Data);
    return 0;
}

输入样例

6
12 2 4 87 10 2
4
2 12 87 5

输出结果

2 is found and deleted.
12 is found and deleted.
87 is found and deleted.
Finding Error: 5 is not in.
5 is inserted as the last element.
Wrong Position for Insertion
Wrong Position for Deletion
10 4 2 5 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值