一、数据结构及其概念
数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成。
数据:客观事物的符号表示
数据元素:数据的基本单位
数据对象:性质相同的数据元素的集合
数据结构:
是指相互之间具有一定联系的数据元素的集合。元素之间的相互关系称为逻辑结构。
数据的逻辑结构:
1、线性结构
(1)一般线性表
(2)受限线性表:
<1>栈 <2>队列 <3>串 <4>数组 <5>广义表
2、非线性结构
(1)集合
(2)树形结构
(3)图状结构
3、一般线性表的作用:存储数据
按照物理结构划分:连续式/非连续式
实现方式:使用连续内存/使用非连续内存
二、算法
1、算法:解决问题的步骤的描述,在计算机中表现为指令的有限序列
2、算法的特性:
(1):I/O:算法具有0个或多个输入,至少有一个输出
(2):有穷性:无死循环,能在可以接受的时间内完成
(3)确定性:算法的每一步骤都具有确定含义,不会出现二义性
(4)可行性:算法的每一步都必须是可行的
3、算法的设计要求:
(1)正确性 (2)可读性 (3)健壮性 (4)时间效率高。储存量低
三、链表
1、链表的冒泡排序
对链表进行冒泡排序的基本思想就是对当前还未排好序的范围内的全部节点,自上而下对相邻的两个节点依次进行比较和调整,让键值(就是用它排 序的字段,我 们取学号num为键值)较大的节点往下沉,键值较小的往上冒。即:每当两相邻的节点比较后发现它们的排序与排序要求相反时,就将它们互换。
单向链表的冒泡排序图示:
---->[1]---->[3]---->[2]...---->[n]---->[NULL](原链表)
head 1->next 3->next 2->next n->next
---->[1]---->[2]---->[3]...---->[n]---->[NULL](排序后链表)
head 1->next 2->next 3->next n->next
图14:有N个节点的链表冒泡排序
任意两个相邻节点p、q位置互换图示:
假设p1->next指向p,那么显然p1->next->next就指向q,
p1->next->next->next就指向q的后继节点,我们用p2保存
p1->next->next指针。即:p2=p1->next->next,则有:
[ ]---->[p]---------->[q]---->[ ](排序前)
p1->next p1->next->next p2->next
图15
[ ]---->[q]---------->[p]---->[ ](排序后)
1、排序后q节点指向p节点,在调整指向之前,我们要保存原p的指向节点地址,即:p2=p1->next->next;
2、顺着这一步一步往下推,排序后图16中p1->next->next要指的是p2->next,所以p1->next->next=p2->next;
3、在图15中p2->next原是q发出来的指向,排序后图16中q的指向要变为指向p的,而原来p1->next是指向p的,所以p2->next=p1->next;
4、在图15中p1->next原是指向p的,排序后图16中p1->next要指向q,原来p1->next->next(即p2)是指向q的,所以p1->next=p2;
5、至此,我们完成了相邻两节点的顺序交换。
6、下面的程序描述改进了一点就是记录了每次最后一次节点下沉的位置,这样我们不必每次都从头到尾的扫描,只需要扫描到记录点为止。 因为后面的都已经是排好序的了。
2、链表的逆置
<span style="font-size:18px;"><strong>#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
}Node;
//创建链表
Node *CreatList(void)
{
int val, i, n;
Node *phead, *p, *q;
phead = NULL;
printf("请输入您要建立的链表长度:\n");
scanf("%d", &n);
printf("请输入您要输入的数据:\n");
for(i=0; i<n; ++i)
{
scanf("%d", &val);
p = (Node *)malloc(sizeof(Node));
p->data = val;
if(NULL == phead)
q = phead = p;
else
q->next = p;
q = p;
}
p->next = NULL;
return phead;
}
//链表的逆置
Node *ReverseList(Node *phead)
{
Node *p, *q, *r;
p = phead;
q=r=NULL;
while(p)
{
q = p->next;
p->next = r;
r = p;
p = q;
}
return r;
}
//输出链表
void ShowList(Node *phead)
{
Node *p;
p = phead;
while(p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main(void)
{
Node *phead;
phead = CreatList();
printf("链表逆置前的数据:\n");
ShowList(phead);
phead = ReverseList(phead);
printf("链表逆置后的数据:\n");
ShowList(phead);
return 0;
}
</strong></span>