数据结构之线性表顺序存储

本文深入探讨了C++标准模板库STL中的线性表操作,包括初始化、销毁、清空、查找、插入、删除等基本操作,并展示了线性表之间的操作如合并与合并排序。文章详细介绍了线性表的基本结构、回调函数及常用操作函数,旨在为C++开发者提供全面的线性表操作指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#ifndef LIST_H_
#define LIST_H_


#define NULL 0


typedef int Status;


// 函数返回状态码
#define OK 0
#define OVERFLOW 1
#define ERROR 2
#define PARAM_ERROR 3


// 布尔类型说明
typedef int BOOL;


#define TRUE 1
#define FALSE 0


// 数据类型定义
typedef int ElemType;


#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10


// 顺序线性表基本结构
typedef struct {
ElemType *elem;
int length;
int listsize;
}SqList, *PSqList;


// 线性表回调函数
typedef BOOL (*compare) (ElemType *e1, ElemType *e2);
typedef BOOL (*visit) (ElemType *e);


BOOL equal( ElemType *e1, ElemType *e2 );
BOOL output( ElemType *e );


// 线性表基本操作
Status InitList_Sq( PSqList L );
Status DestoryList_Sq( PSqList L );
Status ClearList_Sq( PSqList L );
BOOL ListEmpty_Sq( PSqList L );
int ListLength_Sq( PSqList L );
Status GetElem_Sq( PSqList L, int i, ElemType *pElem );
int LocateElem( PSqList L, ElemType e, compare pFunc );
Status ListInsert_Sq( PSqList L, int i, ElemType e );
Status ListDelete_Sq( PSqList L, int i, ElemType *pElem );
Status PriorElem_Sq( PSqList L, ElemType cur_e, ElemType *ppre_e );
Status NextElem_Sq( PSqList L, ElemType cur_e, ElemType *pnext_e );


// 线性表之间操作
void union_Sq( PSqList La, PSqList Lb );
void MergeList_Sq( PSqList La, PSqList Lb, PSqList Lc );


#endif
#include "../include/list.h"

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

Status InitList_Sq( PSqList L )
{
    L->elem = ( ElemType * )malloc( LIST_INIT_SIZE * sizeof( ElemType ) );

    if ( L->elem == NULL ) {
        return OVERFLOW;
    }

    L->length = 0;
    L->listsize = LIST_INIT_SIZE;
    return OK;
}

Status DestoryList_Sq( PSqList L )
{
    free( L->elem );
    L->elem = NULL;
    L->length = 0;
    L->listsize = 0;
    return OK;
}

Status ClearList_Sq( PSqList L )
{
    L->length = 0;
    memset( L->elem, 0, L->listsize * sizeof( ElemType ) );
    return OK;
}

BOOL ListEmpty_Sq( PSqList L )
{
    if ( L->elem == NULL || L->length == 0 ) {
        return TRUE;
    }

    return FALSE;
}


int ListLength_Sq( PSqList L )
{
    return L->length;
}

Status GetElem_Sq( PSqList L, int i, ElemType *pElem )
{
    if ( i < 1 || i > L->length ) {
        return ERROR;
    }

    *pElem = L->elem[i - 1];
    return OK;
}

int LocateElem( PSqList L, ElemType e, compare pFunc )
{
    int nCnt;

    if ( L == NULL || pFunc == NULL ) {
        return ERROR;
    }

    for ( nCnt = 0; nCnt < L->length; ++nCnt ) {
        if ( pFunc( &e, &( L->elem[nCnt] ) ) ) {
            return nCnt - 1;
        }
    }

    return 0;
}

Status ListInsert_Sq( PSqList L, int i, ElemType e )
{
    ElemType *newbase	= NULL;
    ElemType *pInsert	= NULL;
    ElemType *pEnd		= NULL;

    if ( i < 1 || i > L->length + 1 ) {
        return ERROR;
    }

    if ( L->length >= L->listsize ) {
        newbase = ( ElemType * )realloc( L->elem,
                                         ( L->listsize + LISTINCREMENT ) * sizeof( ElemType ) );

        if ( newbase == NULL ) {
            return OVERFLOW;
        }

        L->elem = newbase;
        L->listsize += LISTINCREMENT;
    }

    pEnd = &( L->elem[L->length - 1] );
    pInsert = &( L->elem[i - 1] );

    for ( ; pEnd >= pInsert; --pEnd ) {
        *( pEnd + 1 ) = *( pEnd );
    }

    *pInsert = e;
    ++L->length;
    return OK;
}

Status ListDelete_Sq( PSqList L, int i, ElemType *pElem )
{
    ElemType *pDeleteElem	= NULL;
    ElemType *pEndElem		= NULL;

    if ( pElem == NULL || L == NULL ) {
        return PARAM_ERROR;
    }

    if ( i < 1 || i > L->length ) {
        return ERROR;
    }

    pDeleteElem = &( L->elem[i - 1] );
    *pElem = *pDeleteElem;
    pEndElem = &( L->elem[L->length - 1] );

    for ( ++pDeleteElem; pDeleteElem <= pEndElem; ++pDeleteElem ) {
        *( pDeleteElem - 1 ) = *( pDeleteElem );
    }

    --L->length;
    return OK;
}

Status PriorElem_Sq( PSqList L, ElemType cur_e, ElemType *ppre_e )
{
    ElemType *pBegin = NULL;
    ElemType *pEnd = NULL;

    if ( L == NULL || ppre_e == NULL ) {
        return ERROR;
    }

    if ( L->length <= 2 ) {
        return ERROR;
    }

    pBegin = &( L->elem[1] );
    pEnd = &( L->elem[L->length - 1] );

    for ( ; pBegin <= pEnd; ++pBegin ) {
        if ( *pBegin == cur_e ) {
            *ppre_e = *( pBegin - 1 );
            return OK;
        }
    }

    return ERROR;
}

Status NextElem_Sq( PSqList L, ElemType cur_e, ElemType *pnext_e )
{
    ElemType *pBegin = NULL;
    ElemType *pEnd = NULL;

    if ( L == NULL || pnext_e == NULL ) {
        return ERROR;
    }

    if ( L->length <= 2 ) {
        return ERROR;
    }

    pBegin = &( L->elem[0] );
    pEnd = &( L->elem[L->length - 2] );

    for ( ; pBegin <= pEnd; ++pBegin ) {
        if ( *pBegin == cur_e ) {
            *pnext_e = *( pBegin + 1 );
            return OK;
        }
    }

    return ERROR;
}

Status ListTraverse( PSqList L, visit pFunc )
{
    ElemType *pBegin = NULL;
    ElemType *pEnd = NULL;

    if ( L == NULL || L->length < 1 ) {
        return ERROR;
    }

    pBegin = &( L->elem[0] );

    for ( pEnd = &( L->elem[L->length - 1] ); pBegin != pEnd; ++pBegin ) {
        if ( !pFunc( pBegin ) ) {
            return ERROR;
        }
    }

    return OK;
}

void union_Sq( PSqList La, PSqList Lb )
{
    int La_length = ListLength_Sq( La );
    int Lb_Length = ListLength_Sq( Lb );
    int nCnt;
    ElemType e;

    for ( nCnt = 1; nCnt < La_length; ++nCnt ) {
        GetElem_Sq( Lb, nCnt, &e );

        if ( !LocateElem( La, e, equal ) ) {
            ListInsert_Sq( La, ++La_length, e );
        }
    }
}

BOOL equal( ElemType *e1, ElemType *e2 )
{
    if ( *e1 == *e2 ) {
        return TRUE;
    }

    return FALSE;
}

BOOL output( ElemType *e )
{
    if ( e == NULL ) {
        return FALSE;
    }

    printf( "%d", *e );
    return TRUE;
}

void MergeList_Sq( PSqList La, PSqList Lb, PSqList Lc )
{
	int LaCnt = 1, LbCnt = 1;
	int LcCnt = 0;

	ElemType ae;
	ElemType be;

	int La_length = ListLength_Sq(La);
	int Lb_length = ListLength_Sq(Lb);

	InitList_Sq(Lc);

	while (LaCnt <= La_length && LbCnt <= Lb_length)
	{
		GetElem_Sq(La, LaCnt, &ae);
		GetElem_Sq(Lb, LbCnt, &be);

		if (ae <= be)
		{
			ListInsert_Sq(Lc, ++LcCnt, ae);
			++La_length;
		}
		else
		{
			ListInsert_Sq(Lc, ++LcCnt, be);
			++Lb_length;
		}
	}

	while (LaCnt <= La_length)
	{
		GetElem_Sq(La, LaCnt++, &ae);
		ListInsert_Sq(Lc, ++LcCnt, ae);
	}

	while (LbCnt <= Lb_length)
	{
		GetElem_Sq(La, LbCnt++, &be);
		ListInsert_Sq(Lc, ++LcCnt, be);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值