数据结构学习笔记【第2章 线性表】
2.1 线性表的类型定义
线性结构特点:
- 在数据元素的非空有限集中
- 存在唯一的头和尾
- 每个元素只存在一个前驱(头除外)
- 每个元素只存在一个后继(尾除外)
线性表是n个数据元素的有限序列,有顺序和链式两种结构。
2.2线性表的顺序表示和实现
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//默认函数类型
typedef int ElemType;//数据元素类型
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef struct {
ElemType* elem;
int length;
int listsize;
}SqList;
Status InitList_Sq(SqList& L);
//算法2.3 初始化顺序线性表
Status ListInsert_Sq(SqList& L, int i, ElemType e);
//算法2.4 线性表的插入操作
Status ListDelete_Sq(SqList& L, int i, ElemType& e);
//算法2.5 线性表的删除操作
int LocateElem_Sq(SqList L, ElemType e);
//算法2.6 线性表的查找
void MergeList_Sq(SqList La, SqList Lb, SqList& Lc);
//算法2.7 顺序表的合并
int main()
{
SqList L;
InitList_Sq(L);
ElemType e = 3;
ListInsert_Sq(L, 1, e);
int i = LocateElem_Sq(L, 3);
printf("%d\n", i);
ListDelete_Sq(L, 1, e);
printf("%d\n", L.length);
system("pause");
return 0;
}
Status InitList_Sq(SqList& L)
{
L.elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
if (!L.elem) exit(OVERFLOW);
L.length = 0;
L.listsize = LIST_INIT_SIZE;
return OK;
}
Status ListInsert_Sq(SqList& L, int i, ElemType e)
{
if (i<1 || i>L.length + 1) return ERROR;
if (L.length > L.listsize) {
ElemType* newbase;
newbase = (ElemType*)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
if (!newbase) exit(OVERFLOW);
L.elem = newbase;
L.listsize += LISTINCREMENT;
}
ElemType* q;
q = &(L.elem[i - 1]);
ElemType* p;
for (p = &(L.elem[L.length - 1]); p >= q; --p)
*(p + 1) = *p;
*q = e;
++L.length;
return OK;
}
Status ListDelete_Sq(SqList& L, int i, ElemType& e)
{
if ((i < 1) || (i > L.length)) return ERROR;
ElemType* p;
p = &(L.elem[i - 1]);
e = *p;
ElemType* q;
q = L.elem + L.length - 1;
for (++p; p <= q; ++p)
* (p - 1) = *p;
--L.length;
return OK;
}
int LocateElem_Sq(SqList L, ElemType e)
{
int i = 1;
ElemType* p;
p = L.elem;
while (i <= L.length && p[i - 1] != e)
++i;
if (i <= L.length)
return i;
else
return 0;
}
void MergeList_Sq(SqList La, SqList Lb, SqList& Lc)
{
ElemType* pa, * pb;
pa = La.elem; pb = Lb.elem;
Lc.length = La.length + Lb.length;
Lc.listsize = Lc.length;
ElemType* pc;
Lc.elem = (ElemType*)malloc(Lc.listsize * sizeof(ElemType));
pc = Lc.elem;
if (!Lc.elem) exit(OVERFLOW);
ElemType* pa_last, * pb_last;
pa_last = La.elem + La.length - 1;
pb_last = Lb.elem + Lb.length - 1;
while (pa <= pa_last && pb <= pb_last) { //归并
if (*pa <= *pb)
* pc++ = *pa++;
else
*pc++ = *pb++;
}
while (pa <= pa_last)* pc++ = *pa++;//插入La剩余元素
while (pb <= pb_last)* pc++ = *pb++;//Lb...
}
2.3 线性表的链式表示和实现
2.3.1 线性链表
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;//默认函数类型
typedef int ElemType;//数据元素类型
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode,*LinkList;
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
void print_L(LinkList L);
Status GetElem_L(LinkList L, int i,ElemType& e);
//算法2.8 获取链表中元素
Status ListInsert_L(LinkList& L, int i, ElemType e);
//算法2.9 向链表中插入节点
Status ListDelete_L(LinkList& L, int i, ElemType& e);
//算法2.10 删除链表中节点
void CreatList_L(LinkList& L, int n);
//算法2.11 创建链表
void MergeList_L(LinkList& La, LinkList& Lb, LinkList& Lc);
//算法2.12 归并单链表
int main()
{
LinkList L;
CreatList_L(L, 3);
ListInsert_L(L, 1, 3);
ListInsert_L(L, 2, 4);
print_L(L);
LinkList L2;
CreatList_L(L2, 3);
print_L(L2);
LinkList L3;
CreatList_L(L3, 0);
MergeList_L(L, L2, L3);
print_L(L3);
system("pause");
return 0;
}
void print_L(LinkList L)
{
LNode* p;
p = L;
p = p->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
Status GetElem_L(LinkList L, int i, ElemType& e)
{
LNode* p;
p = L->next;
int j = 1;
while (p && j < i) {
p = p->next;
j++;
}
if (!p || j > i)return ERROR;
e = p->data;
return OK;
}
Status ListInsert_L(LinkList& L, int i, ElemType e)
{
LNode* p;
p = L;
int j = 0;
while (p && j < i - 1)
{
p = p->next;
j++;
}
if (!p || j > i - 1)return ERROR;
LNode* s;
s = (LinkList)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
Status ListDelete_L(LinkList& L, int i, ElemType& e)
{
LNode* p;
p = L;
int j = 0;
while (p && j < i - 1)
{
p = p->next;
j++;
}
if (!(p->next) || j > i - 1)return ERROR;
LNode* q;
q = p->next;
p->next = q->next;
free(q);
return OK;
}
void CreatList_L(LinkList& L, int n)
{
L = (LinkList)malloc(sizeof(LNode));
L->data = n;
L->next = NULL;
int i;
for (i = 0; i <n; i++)
{
LNode* p;
p = (LinkList)malloc(sizeof(LNode));
printf("Please input the Node Value:");
scanf_s("%d", &p->data);
p->next = L->next;
L->next = p;
}
}
void MergeList_L(LinkList& La, LinkList& Lb, LinkList& Lc)
{
LNode* pa, * pb;
pa = La->next;
pb = Lb->next;
LNode* pc;
pc = La;
Lc = pc;
/*while (pa && pb)
{
if (pa->data <= pb->data) {
pc->next = pa;
pc = pa;
pa = pa->next;
}
else {
pc->next = pb;
pc = pb;
pb = pb->next;
}
pc->next = pa ? pa : pb;
}*/
while (pa)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
while (pb)
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
- my version
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode* next;
}LNode,*LinkList;
int CreatList_L(LinkList& L, int n);
int ListInsert_L(LinkList& L,int i, ElemType e);
int ListDelete_L(LinkList& L, int i);
void print_L(LinkList L);
int main()
{
LinkList L;
CreatList_L(L, 3);
print_L(L);
ListInsert_L(L, 1, 6);
print_L(L);
ListDelete_L(L, 2);
print_L(L);
system("pause");
return 0;
}
void print_L(LinkList L)
{
LNode* p;
p = L;
p = p->next;
printf("L(Length:%d):", L->data);
while (p)
{
printf(" %d ", p->data);
p = p->next;
}
printf("\n");
}
int CreatList_L(LinkList& L, int n)
{
L = (LinkList)malloc(n * sizeof(LNode));
if (!L) return 0 ;
L->data = n;
L->next = NULL;
int i;
for (i = 0; i < n; i++)
{
LNode* p;
p = (LNode*)malloc(sizeof(LNode));
if (!p) return 0;
printf("Please input the Node Value:");
scanf_s("%d", &p->data);//默认int类型
p->next = L->next;
L->next = p;
}
return 1;
}
int ListInsert_L(LinkList& L,int i, ElemType e)
{
LNode* p;
p = L;
int j;
for (j = 0; j < i-1; j++)
p = p->next;
if (!(p->next) || j > i - 1) return ERROR;
LNode* s;
s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
L->data++;
return OK;
}
int ListDelete_L(LinkList& L, int i)
{
LNode* p;
p = L;
int j;
for (j = 0; j < i - 1; j++)
p = p->next;
if (!(p->next) || j > i - 1) return ERROR;
LNode* s;
s = (LNode*)malloc(sizeof(LNode));
s = p->next;
p->next = s->next;
L->data--;
return OK;
}
静态链表
- 借用一维数组来描述线性链表
#define MAXSIZE 100
typedef struct {
ElemType data;
int cur;//游标
}component,SLinkList[MAXSIZE];
2.3.2 循环链表
- 表中最后一个节点 的头指针指向头节点
2.3.3 双向链表
- 有两个指针域,一个指向后继,一个指向前驱
typedef struct DuLNode {
ElemType DuLNode;
struct DuLNode* prior;
struct DuLNode* next;
}DuLNode,*DuLinkList;
2.4 一元多项式的表示及相加
线性表的应用
- Pn(x)=p0 + p1x + p2x2 + … + pnxn
- 顺序存储结构,相加简单,但存储的最大长度很难确定。
- 若只对多项式求值则应使用顺序存储结构,若要改变多项式的系数和指数的运算则应使用链式存储结构。
typedef struct {
float coef;
int expn;
}term,ElemType;
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
typedef LinkList polynomical;