链表

这篇博客讨论了线性表的链表实现,包括带头结点的链式表操作,如创建、查找、插入和删除。此外,还介绍了多项式的加法和乘法运算,以及链表的反转。博客提供了相关函数的接口定义和示例,以及针对不同情况的测试用例,包括空链表、零多项式和不同长度的多项式。最后,简述了广义表的概念,它是线性表的推广,元素可以是单元素或另一个广义表。

线性表的数组实现

typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last;
};
 
/* 初始化 */
List MakeEmpty()
{
    List L;
 
    L = (List)malloc(sizeof(struct LNode));
    L->Last = -1;
 
    return L;
}
 
/* 查找 */
#define ERROR -1
 
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;   
}

线性表的链表实现(此处插入与删除采用的是序号)

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

typedef int ElementType;
typedef struct LNode *List;
struct LNode{
    ElementType Data;
    List Next;
};

struct LNode L;
List PtrL;

//求表长 O(n)

int Length( List PtrL )
{
    List p = PtrL;
    int n = 0 ;
    while (p->Next != NULL )
    {
        n++;
        p = p->Next;
    }
    return n;
}

// 按序号查找 O(n)

List FindKth( List PtrL, int K)
{
    List p = PtrL;
    int i = 1;
    while ( i < K && p->Next != NULL )
    {
        i++;
        p = p->Next;
    }
    if (i==K) return p;
    else return NULL;
}

// 按值查找 O(n)

List Find( ElementType X, List PtrL )
{
    List p = PtrL;
    while ( p->Next != NULL && p->Next->Data != X)
        p = p->Next;
//    if (p->Next == NULL ) return NULL;
//    else return p->Next;
    return p->Next;
}

// 按序号插入: 在第i-1个结点后插入一个值为X的新结点 O(n)
// 构造一个新结点
// 找到链表的i-1个结点,用p指向
// 修改指针,插入结点(p之后插入新结点s)

List Insert ( ElementType X, int i, List PtrL )
{
    List s ;
    // 新结点插入在表头
    if (i == 1)
    {
        s = (List) malloc(sizeof(struct LNode));
        s->Next->Data = X;
        s->Next->Next = PtrL;
        return s;
    }
    
    // 查找第i-1个结点,并实现插入
    List p;
    p = FindKth( PtrL, i-1 );
    if ( p == NULL)
        return NULL;
    else
    {
        s = (List) malloc(sizeof(struct LNode));
        s->Data = X;
        s->Next = p->Next;
        p->Next = s;
        return PtrL;
    }
}

// 删除链表的第i(1<= i <= n)个位置上的结点 O(n)
// 找到链表的i-1个结点
// 用s指针指向要被删除的结点(p的下一个结点)
// 修改指针,删除s所指结点
// free(s)

List Delete( int i, List PtrL )
{
    List s;
    // 删除的是头结点
    if( i == 1 )
    {
        s = PtrL->Next;
       //判断本身是不是空链表
        if (PtrL->Next != NULL )
            PtrL->Next = PtrL->Next->Next;
        else return NULL;
        free(s);
        return PtrL;
    }
    List p;
    p = FindKth(PtrL, i-1 );
    if (p == NULL )
    {
        printf("第%d个结点不存在", i-1);
        return NULL;
    }
    else if ( p->Next = NULL )
    {
        printf("第%d个结点不存在", i );
        return NULL;
    } //*******这两个判断容易忽略
    else
    {
        s = p->Next;
        p->Next = s->Next;
        free(s);
        return PtrL;
    }
}


带头结点的链式表操作集

本题要求实现带头结点的链式表操作集。

函数接口定义:

List MakeEmpty(); 
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

其中List结构定义如下:

typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

各个操作函数的定义为:

List MakeEmpty():创建并返回一个空的线性表;

Position Find( List L, ElementType X ):返回线性表中X的位置。若找不到则返回ERROR;

bool Insert( List L, ElementType X, Position P ):将X插入在位置P指向的结点之前,返回true。如果参数P指向非法位置,则打印“Wrong Position for Insertion”,返回false;

bool Delete( List L, Position P ):将位置P的元素删除并返回true。若参数P指向非法位置,则打印“Wrong Position for Deletion”并返回false。

裁判测试程序样例:

#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(); 
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

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
        pri
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值