线性结构-数组和链表的实现

连续存储(数组)

1、什么叫数组?

元素的类型相同,大小相等。

2、优缺点?

查询速度快,增加删除慢

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
//定义一个数据类型,名字 Arr,成员分别
struct Arr
{
    int * pBase;      //存储的是数组第一个元素的地址
    int len;          //数组的长度
    int cnt;          //当前数组有效元素的个数
    int increment;    //自动增长因子,扩容
};
//参数一定要传地址,如果是变量只是把12个字节赋给了另12个字节,进行初始化
void init_arr(struct Arr * pArr , int length)
{
    pArr->pBase = (int *)malloc(sizeof(int)*length)//相当于指针变量中结构体变量pBase成员,返回二十四个字节的第一个字节
        if(NULL == pArr->pBase) //检测是否分配成功
        {
            printf("动态内存分配失败!\n");
            exit(-1); //终止整个程序
        }
        else
        {
            pArr->len = length;
            pArr->cnt = 0;
        }
};
//添加到数组尾部
bool append_arr(struct Arr * pArr , int val)
{
    //满时直接返回
    if(is_full(pArr))
        return false;
    //不满追加
    else
        pArr->pBase[pArr->cnt] = val ;
        pArr->cnt++
};
//插入指定位置,下标为0的是第一个元素
bool insert_arr(struct Arr * pArr,int pos,int val)
{
    int i ;
    if(is_full(pArr)) return false;
    if(pos<1||pos>pArr->cnt+1) return false;
    for(i = pArr->cnt - 1; i>=pos-1; --1)
    {
        pArr->pBase[i+1] = pArr->pBase[i];// 数组下标灯油POS的元素向后移
    }
    pArr->pBase[pos-1] = val;    //赋值POS位置
    pArr->cnt++;
    return true;
};
bool get();
//是否为空
bool is_empty(struct Arr * pArr)
{
    if(0== pArr->cnt)
    {
        return true;
    }
    else
    {
        return false;
    }
};
bool delete_arr(struct Arr * pArr,int pos,int val)
{
    int i;
    if(is_empty(pArr))
    {
        return false;
    }
    if(pos<1 || pos>pArr->cnt)
    {
        return false;
    }
    *val = pArr->pBase[pos-1]; //返回删除的元素
    for(i=pos;i<pArr->cnt ; ++i)
    {
        pArr->pBase[i-1] = pArr->pBase[i];
    }
    pArr->cnt--;
    return true ;
};
//是否满了
bool is_full(struct Arr * pArr)
{
    if(pArr->cnt == pArr->len)
        return true;
    else
        return false;
};
void sort_arr(struct Arr * pArr)
{
    int i,j,t;
    for(i=0;i<pArr->cnt;++i)
    {
        for(j=i+1; j<pArr->cnt ;++j)
        {
            if(pArr->pBase[i] > pArr->pBase[j])
            {
               t=pArr->pBase[i];
               pArr->pBase[i]= pArr->pBase[j];
               pArr->pBase[j]=t;
            };
        }
    }

};
//最好传地址,不需要重新分配内存,输出
void show_arr(struct Arr * pArr)
{
    if(is_empty(pArr))
    {
     printf("数组为空!\n");
    }
    else
    {
     for(int i = 0; i<pArr->len;++i)
     {
     printf("%d",pArr->pBase[i]);
     }
    }
};
//倒置
void inversion_arr(struct Arr * pArr)
{
    int i =0;
    int j=pArr->cnt-1;
    int t;
    while(i<j)
    {
        t=pArr->pBase[i];
        pArr->pBase[i]=pArr->pBase[j];
        pArr->pBase[j]=t;
        ++i;
        --j;
    }
};

int main(void)
    {
    struct Arr arr; //定义一个数据类型,此时的地址全是垃圾地址
    int val ; //删除时,用来返回删除的元素
    init_arr(&arr,6);
    show_arr(&arr);
    append_arr(&arr , 1);
    insert_arr(&arr , 1,10);
    delete_arr(&arr , 1,&val);
    inversion_arr(&pArr);
    sort_arr(&pArr);
        return 0;
    }

离散存储(链表)

定义:

N个结点离散分配,彼此通过指针相连,分配结点只有一个前驱结点和后续结点,首节点没有前驱结点,尾结点没有后续结点,

首节点:第一个有效结点

尾节点:最后一个有效结点

头节点:第一个有效结点前的节点,头节点不存放数据,但是数据类型跟后面节点的数据类型相同

头指针:指向头节点的指针变量

尾指针:指向尾节点的指针变量

分类:

单链表,

双链表:每个节点有两个指针

循环链表:可以通过任何一个节点找到所有结点

非循环链表

算法:

插入时分析

        删除时分析

需要定义一个中间值

优缺点:

一个节点的生成:

#include <stdio.h>
#include <malloc.h>
//定义节点
typedef struct Node
{
    int data;//数据域
    struct Node *pNext; //指针域
} NODE,*PNODE; //NODE等价于struct NODE ,PNODE等价于struct NODE *

int main(void)
    {
    PNODE pHead = NULL; //等价struct NODE * pHead = null; (定义一个头节点)
    pHead = create_list(); //创建一个非循环单链表并将该链表的第一个单元返回
    traverse_list(pHead);
        return 0;
    }
PNODE create_list(void)
{
    int len = 5;
    int i;
    int val;
    PNODE pHead =(PNODE)malloc(sizeof(NODE)); //NODE结构体值类型,PNODE结构体地址类型
    if(NULL == pHead)
    {
        exit(-1);
    }
    PNODE pTail = pHead; //定义一个尾节点
    pTail->pNext =NULL;  //清空指针域(保证尾节点始终指向最后一个)
    for(i=0 ; i<len ; i++)
    {
       PNODE pNew = (PNODE)malloc(sizeof(NODE));//存放每个节点的临时值
        if(NULL == pNew)
        {
            exit(-1);
        }
        pNew ->data = val; //数据域赋值
        pTail->pNext = pNew; //指向下一个节点
        pNew->pNext = null;  //清空下一个节点的指针域
        pTail=pNew;          //下一个节点赋值给尾节点 (保证pTail 永远指向尾节点这是关键)
    }
    return pHead;
}

//输出
void traverse_list(PNODE pHead)
{
    PNODE p = pHead->pNext; //指向第一个有效节点
    while(NULL !=p)
    {
        printf("输出数据域");
        p=p->pNext;
    }
    return;
}
//是否为空
bool is_empty(PNODE pHead)
{
    if(NULL==pHead->pNext) return true;
    return false;
};
//输出长度
int length_list(PNODE pHead)
{
    int i = 0;
    PNODE p=pHead->pNext;
    while(NULL!=p)
    {
        i++;
        p=pHead->pNext;
    }
    return i;
};
//插入节点(在pHead所指向链表的Pos个节点前面插入个新节点,该值是val)
bool insert_list(PNODE pHead , int pos, int val)
{
    int i=0 ;
    PNODE p =pHead
    while (NULL!=p &&i >pos-1)
    {
        p = p->pNext;
        ++i;
    }
     if(i>pos-1 || NULL == p)//判断最后一个节点的位置以及长度和最后一个节点是否为NULL
     {
         return false;
     }
    PNODE pNew =(PNODE)malloc(sizeof(NODE));
    if(NULL == pNew)
    {
        printf("动态分配内存失败");
    }
    pNew ->data =val;
    PNODE  q=p->pNext;
    p->pNext= pNew;
    pNew->pNext =q;
};
//删除一个元素
bool delete_list(PNODE pHead , int pos, int * val)//val是返回删除的元素
{
    int i=0 ;
    PNODE p =pHead
    while (NULL!=p->pNext &&i >pos-1) //找到要删除节点的前一个节点
    {
        p = p->pNext;
        ++i;
    }
     if(i>pos-1 || NULL == p->pNext)//判断最后一个节点的位置以及长度和最后一个节点是否为NULL
     {
         return false;
     }
    PNODE q=p->pNext;
    *pVal = q ->data;

    //删除
    p->pNext = p->pNext->pNext;
    free(q);
    q=NULL;

};

//排序(链表的排序跟数组的排序不同,但是逻辑相同)
bool sort_list(PNODE pHead)
{
    int i,j,t;
    int len=length_list(pHead);
    PNODE p,q;
    for(i=0,p=pHead->pNext;i=len-1;++i , p=p->pNext)
    {
        for(j=i+1,q=p->pNext;i=len-1;++j,q=q->pNext) //循环的同时移动指针q的位置
        {
            if(p->data > q->data) //类似a[i]>a[j]
            {
                t=p->data;//换值
                p->data = q->data;
                q->data=t;
            }
        }
    }
};

原文地址:https://www.cnblogs.com/zklgy/p/8280757.html

时间: 2024-08-29 01:15:05

线性结构-数组和链表的实现的相关文章

数据结构 线性结构(数组[列表] ,链表 单链表的增删改查**, 线性结构的应用 队列 栈[函数的调用**]),非线性结构 树

数据结构 参考:http://lupython.gitee.io/ 线性结构 就是能够用一根线串起来的数据结构 数组 (列表) 问:申请数组的前提条件是啥? a[12]?内存需要满足的条件? 答:内存必须有一块连续的内存空间 int a[7] : 声明一个数组,这个数组的数组名是 a, 数组的大小是 7, 数组元素的类型是整型. int a[7] = array(1,2,3,4,5,6,7) 问:如何申请内存? 答:C,C++语言,申请:mallco (28).释放:free(28) 问:int

数据结构和算法-数据结构-线性结构-顺序表 链表和哈希表

####################################################### """ # 线性表是最基本的数据结构之一,在实际程序中应用非常广泛,它还经常被用作更复杂的数据结构的实现基础. # 根据线性表的实际存储方式,分为两种实现模型: # 顺序表, # 链表, # 下面分别进行研究, """ ####################################################### &qu

线性结构 —— 数组队列

一.介绍 ?队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的端称为队头. 二.代码 ?使用数组模拟队列,首先编写一个ArrayQueue类 class ArrayQueue { private int maxSize; // 最大容量 private int front; // 指向队列头 private int rear; // 指向队列尾 p

线性结构之双链表实现

#include<stdio.h> #include<malloc.h> #include<stdlib.h> typedef struct node { int data; struct node * prior; struct node * next; }NODE,*PNODE; PNODE createList(PNODE); void travelList(PNODE); void insertList(PNODE,int,int); int lengthLis

原始线性结构数组的实现以及操作

不多说直接上代码: #include <stdio.h> #include <malloc.h> #include <stdlib.h> struct Arr { int *pBase; int len; int cnt; }; void init_arr(struct Arr *pArr,int length);//初始化一个数组 void show_arr(struct Arr *pArr);//显示某一个数组 bool isEmpty(struct Arr *pA

线性结构栈之链表实现

#include<stdio.h> #include<malloc.h> #include<stdlib.h> //结点数据类型 typedef struct Node { int data; struct Node *next; }NODE,*PNODE; //栈数据类型 typedef struct { PNODE top; int cnt; }Stack; //想想看,为什么栈的数据结构是这样,我是这样思考的,如果你不这样写可以, //那你必须造出一个计数的结点和

常见的线性列表结构---【数组、链表、栈、队列、堆】

我们在算法设计当中最常见的线性结构列表无非是一下几种: 1.数组: 数组应该是我最常用的一种.他的存储地址是连续的,就是当我们新开辟一个数组时,我们会给他分配一个连续的地址.由于他的地址是连续的,所以在我们知道他下标的时候,查找元素的速度非常快. 2.链表: 链表中的元素的位置不固定,链表中的每一个结点都一个头指针与尾指针,通过这样把链表中的元素连接起来,所以查找一个元素的时间与该元素所处的位置有关系.但是他在空间上面占有优势. 3.栈: 栈中的元素有一个特点,就是保持" 先进先出"的

c语言实现线性结构(数组与链表)

由于这两天看了数据结构,所以又把大学所学的c语言和指针"挂"起来了. 我是小菜鸟,我为自己代言.下面是我这两天学习的成果(数组和链表的实现,用的是c语言哦!哈哈). (一)数组的实现和操作.代码如下: #include <stdio.h> #include <malloc.h> #include <stdlib.h> struct Array{ int length;//数组长度 int * pBase;//存放数组首元素的地址 int cnt;//

数组和链表的区别以及数组和结构体的区别

1,数组和链表的区别? 链表和数组都叫可以叫做线性表, 数组又叫做顺序表,主要区别在于,顺序表是在内存中开辟一段连续的空间来存储数据,而且必须是相同类型的数据. 而链表是通过存在元素中的指针联系到一起的,每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域,链表既可以靠指针来连接多块不连续的的空间也可以用一段连续的空间, 在逻辑上形成一片连续的空间来存储数据. 两种数据结构各有各的好处,链表方便删除和插入,数组方便排序等. 数组从栈中分配空间, 对于程序员方便快速