数据结构(自用)

 一、跨函数分配内存:只可以通过动态来实现。

eg:#include<stdlib.h>

     main()

{

 int *p;

fun(&p);

...

}

int fun(int **q)

{

 *q = (int *)malloc(4);

}

二、数据存储-->线性结构

线性结构:把所有的结点用一根直线穿起来

连续存储(eg:数组)

void init_arr();

bool append_arr();//追加

bool insert_arr();//插入

bool delete_arr();

int get();

bool is_empty();

bol is_full();

void sort_arr();

void show_arr();//输出

void inversion_arr();//遍历

typedef int  ZHANGSAN  //为int重新取一个名字

int为数据类型

同理,下面这个也是数据类型

struct Student

{

 int sid;

char name[100];

char sex;

}       

因此

typedef  struct Student

{

 int sid;

char name[100];

char sex;

ST;  //把那整个数据类型(struct Student)重新定义为一个ST。

typedef  struct Student

{

 int sid;

char name[100];

char sex;

} *  PST;  //把那整个数据类型(struct Student *)重新定义为一个PST(PST是一个指针)。

typedef  struct Student

{

 int sid;

char name[100];

char sex;

} * PSTU, STU;  //等价于STU代表了struct Student,PSTU代表了struct Student *。

离散存储(链表)

定义:链表:a:n个节点离散分配;b:彼此通过指针相连;c:每个节点只有一个前驱节点(首节点没有),每个节点只有一个后续节点(尾节点没有)。

专业术语:

首节点:第一个有效的节点

尾节点:最后一个有效的节点,它的指针域是空的,因为是最后一个。

头节点:第一个有效节点之前的那个节点,它并不存放有效数据,它的存在是为了方便对链表的                   操作,头节点的数据类型和首节点一样。

头指针:指向头节点的指针变量,它存放了头节点的地址

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

若希望通过一个函数来对链表进行处理,我们至少需要接收链表的哪些信息

长度、首节点、尾节点均不是必须的,头指针是必须的。

typedef  struct Node

{

  int data;   //数据域

  struct Node * pNext;//指针域

}NODE,*PNODE;  //NODE等价于struct Node,PNODE等价于struct Node *

分类:

单链表:

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

循环链表:尾节点指向头节点;可以通过任何一个节点找到其它所有的节点

非循环链表:

算法:

遍历:

查找:

清空:

销毁:

求长度:

排序:

插入节点(q为指向该节点的指针):q->pNext = p->pNext;p->pNext = q;

删除节点: r = p->pNext; p->pNext = p->pNext->pNext;free(r);

                   free p;删除p指向节点所占内存,不是删除p本身所占内存。

链表的优缺点:

线性结构的两种常见应用之一   : 栈(函数调用与内存分配都要用到)

线性结构的两种常见应用之二   : 队列(所有和时间有关的操作都要用到)

程序:

#include<stdio.h>

#include<malloc.h>

#include<stdlib.h>

typedef  struct Node

{

  int data;   //数据域

struct Node * pNext;//指针域

}NODE,*PNODE;  //NODE等价于struct Node,PNODE等价于struct Node *

//函数声明

PNODE create_list(void);

void traverse_list(PNODE pHead);

int main(void)

{

 PNODE  pHead = NULL;  //等价于struct Node * pHead = NULL;

 pHead = create_list();       //create_list()功能:创建一个非循环单链表,并将该链表的首地址赋给                                              pHead

                                           //一个函数分配好内存让另一个函数去使用,前提是动态分配

traverse_list(pHead); 

return 0;

}

//void f()

//{

//  int i;

//  int * p = (int *)malloc(100);//当f运行完之后,p本身的内存释放了,满是malloc动态分                                                                  配的那100个字节还在。

//

PNODE create_list(void)

{

 int i;

int len;//用来存放有效节点的个数

int val;//用来临时存放用户输入的节点的值

//分配了一个不存放有效数据的头节点

PNODE  pHead = (PNODE)malloc(sizeof(NODE)); 

if(NULL==pHead)

{

  printf(“fail to allocate,procedure expired\n”);

  exit(-1);

}

PNODE pTail = pHead;

pTail->pNext = NULL;

printf(“please input the amout  of point: len = ”);

scanf(“%d”,&len)

for(i=0;i<len; ++i)

{

 printf(“please input the th %d point ”,i+1);

 scanf("%d",&val);

PNODE  pNew = (PNODE)malloc(sizeof(NODE)); 

if(NULL==pNew)

{

  printf(“fail to allocate,procedure expired\n”);

  exit(-1);

}

pNew->data = val;

pTail->pNext = pNew;

pNew->pNext = NULL;

pTail = pNew;

}

return pHead;

}

void traverse_list(PNODE pHead)

{

 while(NULL!=p)

{

 printf("%d",p->data);

p = p->pNext;

}

printf("\n");

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值