首页 > 其他分享 >C语言 笔记3

C语言 笔记3

时间:2023-08-20 16:35:24浏览次数:37  
标签:结点 int list 笔记 C语言 链表 array size

可变数组

设计一个Array库,提供数组初始化,数组数据查看和修改的功能,且数组大小可变。

array.h

/*
    可变数组 */

// array_block,每次触发自动增长时增长的数量,记作一个array_block
#define ARRAY_BLOCK 10

typedef struct {
    int size;
    int *array;
} Array;

Array array_create(int init_size);
void array_free(Array *a);
int array_size(const Array *a);
int array_get(const Array *a,int index);
void array_set(Array *a,int index,int value);
void array_inflate(Array *a,int add_size);

Array array_create(int init_size){
    // 初始化数组    
    	Array a = {
        init_size,
        (int*)malloc(sizeof(int)*init_size)
    };
    return a;
}

void array_free(Array *a){
    // 释放数组    
    free(a->array);
    a->size = 0;
    a->array = NULL;
}

int array_size(const Array *a){
    // 读取数组的大小    
    return a->size;
}

int array_get(const Array *a,int index){
    // 读取数组中的成员的值    
    return a->array[index];
}

void array_set(Array *a,int index,int value){
    // 设置数组中成员的值    
    if(index >= a->size){
        // 越界自动增长        
        int over_size = (index+1) - a->size;
        int block_num = (over_size/ARRAY_BLOCK) + 1;
        int add_size = block_num * ARRAY_BLOCK;
        array_inflate(a,add_size);
    }
    // 设置值    
    a->array[index] = value;
}

void array_inflate(Array *a,int add_size){
    // 数组增长    
    int *t = (int*)malloc(sizeof(int)*(a->size+add_size));
    for(int i = 0; i < a->size; i++){
        t[i] = a->array[i];
    }
    free(a->array);
    a->array = t;
    a->size += add_size;
}

测试样例

main.c

#include<stdio.h>
#include<stdlib.h>
#include "array.h"
#include "style.h"

int main(){
    Array arr = array_create(20);
    hr('-',60);
    for(int i = 1; i < 20; i++){
        array_set(&arr,i,i);
        printf("%d ",arr.array[i]);
    }
    printf("\b\n");
    printf("array.size => %d\n",array_size(&arr));
    hr('-',60);
    for(int i = 1; i < 25; i++){
        array_set(&arr,i,i);
        printf("%d ",arr.array[i]);
    }
    printf("\b\n");
    printf("array.size => %d\n",array_size(&arr));
    hr('-',60);

    return 0;
}

输出

------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
array.size => 20
------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 
array.size => 30
------------------------------------------------------------

style.h

void hr(char ch,int num){
    for(int i = 0; i < num; i++){
        if(i!=num-1)
            printf("%c",ch);
        else
            printf("%c\n",ch);
    }
}

链表

声明节点类型

想要建立链表,就需要有一个可以表示单个结点的结构.先声明一个结构体类型.

struct node {
	int data; // 存储数据
	struct node *next; // 结构体指针,指向下一结点
}

可以使用 typedef 来给结构命名.

typedef struct _node *nextNode;
struct node {
	int data; // 存储数据
	nextNode next; // 结构体指针,指向下一结点
}
typedef nextNode List;

创建结点

构建链表时,需要逐个创建结点,并将结点添加在链表中.创建结点可以大致分为三个步骤:

  1. 把结点分配到内存单元中.
  2. 把数据存在结点中.
  3. 把结点插入到链表中.

下面是创建结点的一种方法:

List listadd(List list,int number) /* 添加新节点到链表 */
{
    List new_node = (List)malloc(sizeof(struct _node)); // 把结点分配到内存单元中
    new_node->data = number; // 把数据存在结点中
    /* 把结点插入到链表中 */
    new_node->next = list; 
    list = new_node;
    return list; // 返回链表
}

这是创建结点的一种方法,是我们的教材中讲到的一种方法.这个函数并不会对原来的链表做修改,而是返回一个链表.然后用原来的链表等于函数的返回值.类似这样:

List list = NULL;
list = listadd(list,1);
list = listadd(list,2);

还有一点,如果使用上面这种方法创建新结点,这个链表会是倒序的.如果要创建正序的链表,需要用一个遍历先找到链表的最后一个结点,然后插入新节点.

搜索链表

创建链表后,可能需要去在链表中搜索某一个特定的值.一般情况使用for循环语句去遍历一个链表:

for(p = list; p! = NULL; p = p->next){
    ...CODE...
}

如果在函数内有一个链表的副本,在函数内修改它不会对原链表产生影响时,可以这样写:

for(;list != NULL; list = list->next){
    ...CODE...
}

当然也可以使用while循环去做这件事情:

// p = list;
while(p!=NULL){
    p = p->next;
    ...CODE...
}

因此搜索链表可以写成下面这个函数:

List listsearch(List list,int number) /* 在链表中搜索 */
{
    for(; list!=NULL && list->data != number; list = list->next);
    return list; // 将搜索到的结点返回
}

删除结点

删除结点大概分为三个步骤:

  1. 搜索到要删除的结点.
  2. 让前一个结点与后一个结点链接.
  3. free掉要删除的结点.
List listdel(List list,int number) /* 删除结点 */
{
    List cur = NULL; // 存储当前结点
    List prev = NULL; // 存储上一结点
    for(cur = list,prev = NULL;\
        cur->data!=number && list!=NULL;\
        prev = cur, cur = cur->next);
    if(cur == NULL) // 未找到
    {
        return list;
    }
    else if(prev == NULL) // 在首结点处
    {
        list = list->next;
    }
    else // 搜索到,且不在首结点
    {
        prev = cur->next;
    }
    free(cur);
    return list;
}

结尾

创建搜索删除是我们教材中举的三个例子.当然链表远不止这些.等到以后遇到需要记得东西,再在这里加一下.

标签:结点,int,list,笔记,C语言,链表,array,size
From: https://www.cnblogs.com/orzmiku/p/17644190.html

相关文章

  • C语言 笔记5
    格式化输入输出输入-printfprintf("%[flags][width][.prec][hlL]type...",参数表...);返回值输出的字符数flagFlag含义-左对齐+给一个正数强制加一个+号(space)正数留空0左边补零,不能和左对齐同时使用width和precwidth含义number......
  • 「Python」第一阶段第七章笔记
    函数的多返回值"""函数的多返回值"""defmy_return():return1,2x,y=my_return()print(x,y,type(x),type(y))函数的多种传参方式"""函数的多种传参方式-位置-参数-缺省-不定长"""#位置传参形参实参位置对应defadd(a=0,b=0)......
  • 「Python」第一阶段第五章笔记
    函数的初体验"""函数的初体验"""name="OrzMiku"print(f"{name}这个名字有{len(name)}个字符长")函数的定义"""函数的定义def函数名(参数表):函数体return返回值"""defsayHello():print("HelloW......
  • 「Python」第一阶段第二章 笔记
    字面量#字面量:写在程序中固定的值print(114514)print(1919810)print("HelloWorld")注释"""Python中的多行注释"""print("多行注释用三个引号开头三个引号结尾")#Python中的单行注释print("单行注释以井号开头")变量"""变量名=变量值&......
  • 「Python」第一阶段第三章笔记
    布尔类型和比较运算符"""跳过"""if语句基本格式"""if语句基本格式if条件:代码块"""age=int(input("请输入你的年龄:"))ifage>=18:print("老东西速速爆金币!")quit()print("小东西给我磕一个!")......
  • 「Python」第一阶段第四章笔记
    while循环"""while条件:代码块"""num=255;#python没有++和--whilenum:print(num)num-=1for循环for基础语法"""for循环(感觉更像是一个foreach循环)for临时变量in序列类型:代码块"""name="OrzMiku......
  • 「Python」第二阶段第一章笔记
    初识对象"""初识对象"""#1.设计一个类classStu:name=None#学生姓名gender=None#学生性别nationality=None#学生国籍native_place=None#学生籍贯age=None#学生年龄#2.创建一个对象stu_1=Stu()#3.对象属性进行赋......
  • 计算机萌新的成长历程——初识C语言2
    今天我将分享初识数据类型的学习体会和心得。刚刚开始接触数据类型,我学习到了以下几个数据类型char——字符数据类型short——短整型int——整型long——长整型longlong——更长的整型float——单精度浮点数double——双精度浮点数下面我将分享一下我对这些数据类型的理解。理解这......
  • Linux笔记(银河麒麟V10)
    Linux下切换Python版本$whereispython$rm/usr/bin/python$ln-s/usr/bin/python3.6/usr/bin/python测试:$python--versionPython3.8.2安装Node.js-v18$curlhttps://nodejs.org/dist/v18.17.0/node-v18.17.0-linux-x64.tar.xz--outputnodejs18.tar.xz#......
  • Linux驱动开发详解——学习笔记
    Linux设备驱动概述计算机系统的运转需要软件和硬件共同参与,硬件是底层基础,软件则实现了具体的应用。硬件和软件之间则通过设备驱动来联系。在没有操作系统的情况下,工程师可以根据硬件设备的特点自行定义接口。而在有操作系统的情况下,驱动的架构则由相应的操作系统来定义。驱动存......