1、顺序表的定义
在高级语言(如C语言)环境下:数组具有随机存取的特性,因此,借助数组来描述顺序表。除了用数组来存储线性表的元素之外,顺序表还应该有表示线性表的长度属性,所以用结构类型来定义顺序表类型。
#define MAXSIZE[100] /*数组最大长度*/
typedef sqList { /*定义线性表结构体*/
int data[MAXSEZE]; /*线性表存储元素的数组*/
int length; /*记录线性表的长度*/
}SqList,*sqList; /*线性表的名称*/
三个特性:
1、空间数组是data2;
2、最大长度是MAXSIZE;
3、当前元素个数是length。
2、链表的定义
C语言中用带指针的结构体类型来描述。
struct Lnode{
int data; /*数据域,保存结点的值*/
struct LNode *next; /*指针域*/
}LNode,*LinkList;
typedef struct Lnode LNode; /*变量类型,通常用来定义数据结点*/
typedef struct Lnode *LinkList; /*指针类型,通常用来定义头结点*/
3、基本操作
1)结点的赋值
LNode *p;
p=(LNode*) malloc(sizeof(LNode));
p->data=20;
p->next=NULL;
2)常见的指针操作
①q=p;
注意:结点p,指的是这个结点;指针p,指的是指针指向的这个结点。
②q=p->next;
③p=p->next;
④插入一个结点(后插法):q->next=p->next; q->next=p;
核心:先右后左。
注意:链式结构,要注意不可以出现断链问题,断链的原因是:p指向a,而结点b依赖于p->next。
【易错题】
在一个单链表中,已知q所指结点是p所指结点的前驱结点,若在q和p之间插入s结点,则执行()
A、s->next = p->next; p->next = s;
B、p->next = s->next; s->next = p;
C、q->next = s; s->next = p;
D、p->next = s; s->next = q;
【答案】C
【解析】由题意得,p、q都是结构体指针变量,当p、q指向某个结点的时候,意味着结点的首地址赋予了p、q指针变量,也就是说这两个结点的地址是已知的,所以可以q->next=s,s->next=p;如果只给出的一个结构体指针变量p,要在其后面后面插入一个新的结点,就要考虑到断链的情况。
⑤删除一个结点:
p->next=p-next->next;
4、建立单链表
(1)头插入法建表,可用于链表逆置。
从一个空表开始,重复读入数据,生成新结点,将读入数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头上,直到读入结束标志为止。即每次插入的结点都作为链表的第一个结点。
核心思想:
①分配空间:head= (LNode *) malloc(sizeof(LNode));
②设置next:head->next=NULL;
③插入结点:p->next=head->next; head->next=p;
/*头插入法创建单链表,链表的头结点head作为返回值*/
LNode *create_Linklist(void){
int data;
LNode *head, *p;
head= (LNode *) malloc(sizeof(LNode));
head->next = NULL; /*创建链表的表头结点head*/
while (1){
scanf("%d",&data);
if (data==NULL) break ;
p= (LNode *) malloc(sizeof(LNode));
p->data = data; /*数据域赋值*/
p->next = head->next; /*钩链,新创建的结点总是作为第一个结点*/
head->next=p;
}
return (head);
}
看完代码自问:
①代码本质是什么?
②核心代码是什么?
(2)尾插入法建表
头插入法建立链表虽然算法简单,但生成的链表中结点的次序和输入的顺序相反。若希望二者次序一致,可采用尾插法建表。该方法是将新结点插入到当前链表的表尾,使其成为当前链表的尾结点。
注意:头指针指向头结点,头结点指向首元结点,也就是第一个数据结点,换句话说,头结点不是数据结点,而尾指针指向尾结点。单链表结构,插入和删除必须找到直接前驱,才可以操作。
核心思想:
①分配空间:head=p=(LNode *) malloc(sizeof(LNode));
②置空:p->next=NULL;
③尾指针的插入与复位:
实现插入:q->next=p->next; p->next=q;
尾指针复位问题:p=q;
-
/*尾插入法创建单链表,链表的头结点head作为返回值*/ LNode *create_LinkList(void){ int data; LNode *head,*p, *q; head=p=(LNode *) malloc(sizeof(LNode)); p->next=NULL; /*创建单链表的表头结点head*/ while (1){ scanf("%d",&data); if (data == NULL) break; q = (LNode *) malloc(sizeof(LNode)); q->data=data; /*数据域赋值*/ q->next=p->next; p->next=q; p=q; /*钩链,新创建的结点总是作为最后一个结点*/ } return (head); }
5、线性表常见算法应用
- 双指针
- 哈希
- 数组或单链表逆置
- 数组或单链表旋转
6、算法解法
- 暴力解:枚举方法,这个是底线写法
- 可行解:在暴力解的基础上进行优化,算法两个指标:时间、空间
- 最优解:随缘写,这个是终极目标
7、算法怎么写
- 首先要明确:写的是算法,不是完整程序,有核心代码就行
- 先写结构体定义
- 算法的思想和步骤
- 算法的实现
- 算法复杂度分析:时间复杂度、空间复杂度
8、怎么才能得分
- 写算法思想,图文结合
- 代码注释
- 命名规范,见文知意
- 格式严谨,手动缩进