我们如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(比如查找某个元素,删除某个元素,对所有元素进行排序而执行的相应操作,这个相应的操作也叫算法)。
个体如何保存,个体与个体之间的关系如何保存。
数据结构解决存储的问题,算法解决操作的问题。
解题的方法和步骤
衡量算法的标准:
数据结构是软件中最核心的课程
程序 = 数据的存储 + 数据的操作 + 可以被计算机执行的语言
指针的重要性:
指针是C语言的灵魂
定义:
地址:内存单元的编号。
指针:指针占四个字节
double *q;
double x = 66.6;
q = &x; //x占8个字节,1个字节是8位,1个字节一个地址
double arr[] = {1.1,2.2,3.3};
q = &arr[0];
printf("%p\n",q); //%p实际就是以十六进制输出
q = &arr[1]; //指针变量统一只占四个字节
printf("%p\n",q); //[0]与[1]差八个字节
为了表示一些复杂的数据
struct Student
{
int sid;
char name[200];
int age;
};
struct Student st = {100,"zhangsan",20};
printf("%d, %s, %d\n",st.sid,st.name,st.age);
st.sid = 99;
//st.name = "list";
strcpy(st.name,"list");
st.age = 11;
printf("%d, %s, %d\n",st.sid,st.name,st.age);
结构体是用户根据实际需要自己定义的复合数据类型。
#include
struct Student
{
int sid;
char name[200];
int age;
};
struct Student *pst = &st;
pst->age = 10;
strcpy(pst->name,"li");
pst->sid = 11;
printf("%d, %s, %d\n",pst->sid,pst->name,pst->age);
结构体变量不能加减乘除,但可以相互赋值。
普通结构体变量和结构体指针变量作为函数传参的问题:传结构体变量耗内存,耗时间。
#include
int a[5] = {3,1,4,8,7};
int len;
printf("请输入你需要分配的数组的长度:len = ");
scanf("%d",&len);
int *pArr = (int*)malloc(sizeof(int)*len);
for(int i =0 ;i
代码如下:
#include
#include
#include
using namespace std;
//定义了一个数据类型,该数据类型的名字叫做struct Arr,该数据类型含有三个成员
//分别是pBase,len,cnt;
struct Arr
{
int *pBase; //存储的是数组的第一个元素的地址
int len; //数组所能容纳的最大元素的个数
int cnt; //当前数组有效元素的个数
};
void init_arr(struct Arr * pArray);
bool append_arr(struct Arr &Array, int value); //追加
bool insert_arr(struct Arr &Array, const int pos, int val);
bool delete_arr(struct Arr &Array, const int pos, int &val);
int get(struct Arr &Array, const int &pos);
bool is_empty(const struct Arr &Array);
bool is_full(const struct Arr &Array);
void sort_arr(struct Arr &Array);
void show_arr(const struct Arr &Array);
void inversion_arr(const struct Arr &Array);
void init_arr(struct Arr * pArray)
{
int len = 0;
printf("please input the size of array: ");
scanf("%d",&len);
int *pBase = (int*)malloc(sizeof(int)*len);
pArray->pBase = pBase;
pArray->len = len;
pArray->cnt = 0;
}
void show_arr(const struct Arr &Array)
{
if (is_empty(Array))
printf("array is empty!");
else
{
for(int i = 0;i Array.cnt+1)
return false;
else
{
for(int i = Array.cnt-1;i>= pos-1;i--)
{
Array.pBase[i+1] = Array.pBase[i];
}
Array.pBase[pos-1] = val;
Array.cnt++;
return true;
}
}
bool delete_arr(struct Arr &Array, const int pos, int &val)
{
if (is_empty(Array))
return false;
if (pos<1 || pos>Array.cnt)
return false;
else
{
val = Array.pBase[pos-1];
for(int i = pos; iArray.cnt)
return -1;
return Array.pBase[pos-1];
}
void inversion_arr(const struct Arr &Array)
{
int i =0;
int j = Array.cnt-1;
int temp;
while(i Array.pBase[j])
{
temp = Array.pBase[i];
Array.pBase[i] = Array.pBase[j];
Array.pBase[j] = temp;
}
}
}
}
int main()
{
struct Arr stArray;
init_arr(&stArray);
show_arr(stArray);
append_arr(stArray, 2);
append_arr(stArray, 3);
append_arr(stArray, 6);
append_arr(stArray, 1);
show_arr(stArray);
insert_arr(stArray, 2,89);
show_arr(stArray);
insert_arr(stArray, 9, 2);
show_arr(stArray);
int val = 0;
delete_arr(stArray, 2, val);
printf("删除的是%d\n",val);
show_arr(stArray);
printf("%d\n",get(stArray, 9));
inversion_arr(stArray);
show_arr(stArray);
sort_arr(stArray);
show_arr(stArray);
return 0;
}
1.定义: n个节点离散分配,彼此通过指针相连,每个节点只有一个前驱节点,每个节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点。
专业术语:
首节点:第一个有效节点。
尾节点:最后一个有效节点。
头结点:第一个有效节点之前的那个节点,头结点并不存放有效数据,加头结点的目的主要是为了方便对链表的操作。
头指针:指向头结点的指针变量。
尾指针:指向尾节点的指针变量。
确定一个链表需要几个参数:
2. 分类: