(郝斌讲学)数据结构学习篇(二)---数组的操作连续存储

012.连续存储数组的算法演示

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

一个字节有4个地址。

 

实现一个数组的案例

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>  //包含了exit函数

struct Arr
{
	int * pBase; //数组第一个元素的地址
	int len; //数组的长度
	int cnt; //当前数组有效元素的个数
};

int get();

bool append_arr(struct Arr * pArr, int val);
bool insert_arr(struct Arr * pArr, int pos, int val); //pos值从1开始
bool delete_arr(struct Arr * pArr, int pos, int * pVal);
bool is_empty(struct Arr * pArr);
bool is_full(struct Arr * pArr);

void init_arr(struct Arr * pArr, int len);
void sort_arr(struct Arr * pArr);
void show_arr(struct Arr * pArr);
void inversion_arr(struct Arr * pArr);

int main(void)
{
	struct Arr arr;
	int p;

	init_arr(&arr,8);
	show_arr(&arr);

	append_arr(&arr,1);
	append_arr(&arr,2);
	append_arr(&arr,5);
	append_arr(&arr,6);
	show_arr(&arr);
	
	printf("插入的结果是:");
	insert_arr(&arr, 3, 88);
	insert_arr(&arr, 5, -5);
	insert_arr(&arr, 1, 60);
	show_arr(&arr);

	if(delete_arr(&arr, 2, &p))
	{
		printf("删除成功!\n");
		printf("删除的元素是:%d\n", p);
	}
	else{
		printf("删除失败!\n");
	}
	printf("删除的结果是:");
	show_arr(&arr);
	
	printf("倒置的结果是:");
	inversion_arr(&arr);
	show_arr(&arr);
	
	printf("排序的结果是:");
	sort_arr(&arr);
	show_arr(&arr);

	return 0;
}

//初始化数组
void init_arr(struct Arr *pArr, int length)
{
	pArr->pBase = (int *)malloc(sizeof(int) *length);
	if(NULL == pArr->pBase)
	{
		printf("动态内存分配失败!");
		exit(-1);
	}
	else
	{
		pArr->len = length;
		pArr->cnt = 0;
	}
	return;
}

//判断数组是否为空
bool is_empty(struct Arr * pArr)
{
	if(0 == pArr->cnt)
		return true;
	else
		return false;
}

//显示数组的数据
void show_arr(struct Arr * pArr)
{
	if(is_empty(pArr))
	{
		printf("数组为空!\n");
	}
	else
	{
		for(int i=0; i<pArr->cnt; ++i)
		{
			printf("%d  ", pArr->pBase[i]);
		}
		printf("\n");
	}
}	

//判断数组是否满了
bool is_full(struct Arr * pArr)
{
	if(pArr->cnt == pArr->len)
		return true;
	else
		return false;
}

//追加一个元素
bool append_arr(struct Arr * pArr, int val)
{
	//满是返回false
	if(is_full(pArr))
		return false;

	//不满时追加
	pArr->pBase[pArr->cnt] = val;
	(pArr->cnt)++;
	return true;
}

//插入一个元素
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; --i)
	{
		pArr->pBase[i+1] = pArr->pBase[i];
	}
	pArr->pBase[pos-1] = val;
	(pArr->cnt)++;
	return true;
}

//删除元素
bool delete_arr(struct Arr * pArr, int pos, int * pVal)
{
	int i;

	if(is_empty(pArr))
		return false;
	if(pos < 1 || pos < pArr->cnt)
		return false;
	
	*pVal = pArr->pBase[pos-1];
	for(i=pos; i<pArr->cnt; ++i)
	{
		pArr->pBase[i-1] = pArr->pBase[i];
	}
	(pArr->cnt)--;
	return true;
}

//倒置数组
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;
	}
	return;
}

//排序数组
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;
			}
		}
	}
}

015.type的用法

 

#include <stdio.h>

 

typedef struct Node

{

int data;  //数据域

struct Node * pNext; //指针域

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

 

int main(void)

{

 

return 0;

}

 

typedef int ZHENGXING;

int i = 10;  ==>>ZHENGXING i = 10;

 

016.链表的定义

离散存储[链表]n个节点离散分配,彼此通过指针相连。每个节点只有一个前驱节点,每个节点只有一个后续节点。首节点没有前驱节点,尾节点没有后续节点。

 

专业术语:

首节点:第一个有效节点

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

头结点:第一个有效节点之前的那个节点。没有存放有效数据,也没有存放有效数据的个数。目的是为了方便对链表的操作。

头指针:指向头结点的指针变量。

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

 

017.如果希望通过一个函数来对链表进行处理,我们至少需要链表的哪些参数?

只需要一个参数:头指针

因为我们通过头指针就可以推算出链表的其他所有信息。

 

019.链表的分类

单链表

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

循环链表:能通过任何一个节点找到其他所有的节点

非循环链表

你可能感兴趣的:(数据结构,链表,存储,单链表,typedef)