线性结构
一、认识线性表
- 定义:
线性表是n个数据元素的有限序列。 - 特点
- 同一线性表中的元素具有相同特性
- 复杂的数据元素可由若干个数据项组成
- 相邻数据元素之间存在序偶关系
- 线性表的ADT
ADT List{
数据对象:D
数据关系:R1
基本操作:
InitialList(&L);
DestroyList(&L);
ClearList(&L);
ListEmpty(L);
ListLength(L);
GetElem(L, i, &e);
LocateElem(L, e, compare());
PriorElem(L, cur_e, &pre_e);
NextElem(L, cur_e, &next_e);
ListInsert(&L, i, e);
ListDelete(&L, i, &e);
ListTraverse(L, visit());
}
- 分类
- 顺序表:数据元素存储在内存的不同位置,位置关系对应逻辑关系,通常呈序偶关系的数据元素其内存中的存储位置也相邻。
- 链式表:数据元素存储在内存的不同位置,位置关系无法体现序偶关系,需要额外的存储空间或信息来标记序偶关系
二、顺序表
- 定义:将线性表中的元素相继存放在一个连续的存储空间中。
- 特点:
- 存储结构:类似一维数组
- 存取方式:顺序访问,可以随机存取。
- 优点:逻辑上相邻,物理上也相邻,可随机存取其中任一元素,存储位置可用公式计算。
- 缺点:插入删除的附加操作过多,移动大量的元素。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define List_SIZE 100
#define LISTINCREMENT 10
struct SqList
{
int* memory;
int length;
int size;
};
struct SqList* initList();
int locateItem(struct SqList* MyList, int x);
int ListLength(struct SqList* MyList);
int GetItem(struct SqList* MyList, int i);
void insertList(struct SqList* MyList, int i, int data);
void deleteList(struct SqList* MyList, int i);
struct SqList* Union(struct SqList* list1, struct SqList* list2);
struct SqList* intersection(struct SqList* list1, struct SqList* list2);
struct SqList* MergeList_Sq(struct SqList* list1, struct SqList* list2);
int main()
{
struct SqList* mylist = initList();
insertList(mylist, 1, 1);
insertList(mylist, 2, 2);
insertList(mylist, 3, 3);
insertList(mylist, 4, 4);
for (int i = 0; i < mylist->length; i++)
{
printf("%d\t", mylist->memory[i]);
}
printf("\n");
printf("%d\n", locateItem(mylist, 3));
printf("%d\n", GetItem(mylist, 2));
deleteList(mylist, 2);
printf("%d\n", GetItem(mylist, 2));
for (int i = 0; i < mylist->length; i++)
{
printf("%d\t", mylist->memory[i]);
}
printf("\n");
printf("%d\n", locateItem(mylist, 3));
struct SqList* A = initList();
insertList(A, 1, 2);
insertList(A, 2, 3);
insertList(A, 3, 4);
for (int i = 0; i < A->length; i++)
{
printf("%d\t", A->memory[i]);
}
printf("\n");
struct SqList* B = initList();
insertList(B, 1, 41);
insertList(B, 2, 3);
insertList(B, 3, 4);
for (int i = 0; i < B->length; i++)
{
printf("%d\t", B->memory[i]);
}
printf("\n");
struct SqList* C = initList();
C = Union(A, B);
for (int i = 0; i < C->length; i++)
{
printf("%d\t", C->memory[i]);
}
printf("\n");
C = intersection(A, B);
for (int i = 0; i < C->length; i++)
{
printf("%d\t", C->memory[i]);
}
printf("\n");
C = MergeList_Sq(A, B);
for (int i = 0; i < C->length; i++)
{
printf("%d\t", C->memory[i]);
}
printf("\n");
system("pause");
return 0;
}
struct SqList* initList()
{
struct SqList* MyList = (struct SqList *)malloc(sizeof(struct SqList));
assert(MyList);
MyList->memory = (int*)malloc(sizeof(int) * List_SIZE);
assert(MyList->memory);
MyList->length = 0;
MyList->size = List_SIZE;
return MyList;
}
int locateItem(struct SqList* MyList, int x)
{
int* temp = MyList->memory;
int count = 0;
for (; temp <= (temp + MyList->length - 1); temp++)
{
count++;
if (*(temp) == x)
{
return count;
}
}
printf("未找到指定元素!\n");
return -999999;
}
int ListLength(struct SqList* MyList)
{
return MyList->length;
}
int GetItem(struct SqList* MyList, int i)
{
if (i >= 1 && i <= MyList->length)
{
return *(MyList->memory + i - 1);
}
else
{
printf("提取失败!\n");
return -99999;
}
}
void insertList(struct SqList* MyList, int i, int data)
{
if (i < 0 || i > MyList->size)
{
printf("插入失败\n");
return 0;
}
int* temp = MyList->memory + i - 1;
for (int* p = MyList->memory + MyList->length - 1; p >= temp; p--)
{
*(p + 1) = *p;
}
*(MyList->memory + i - 1) = data;
MyList->length++;
}
void deleteList(struct SqList* MyList, int i)
{
if (i < 1 || i > MyList->size)
{
printf("删除失败!\n");
return;
}
int* temp = MyList->memory + i - 1;
int* tail = MyList->memory + MyList->length - 1;
for (++temp; temp <= tail; ++temp)
{
*(temp - 1) = *(temp);
}
MyList->length--;
}
struct SqList* Union(struct SqList* list1, struct SqList* list2)
{
int m = list1->length;
int n = list2->length;
struct SqList* list3 = initList();
for (int i = 1; i <= m; i++)
{
insertList(list3, i, list1->memory[i - 1]);
}
for (int i = 1; i <= n; i++)
{
int count = 1;
int j = 0;
while(list3->memory[j] != list2->memory[i - 1] && j < list3->length)
{
j++;
if (list3->memory[j] == list2->memory[i - 1])
{
break;
}
}
if (j == list3->length)
{
insertList(list3, count + list3->length, list2->memory[i - 1]);
count++;
}
}
return list3;
}
struct SqList* intersection(struct SqList* list1, struct SqList* list2)
{
int m = list1->length;
int n = list2->length;
struct SqList* list3 = initList();
for (int i = 1; i <= m; i++)
{
insertList(list3, i, list1->memory[i - 1]);
}
for (int i = 1; i <= n; i++)
{
int j = 0;
while (list3->memory[j] != list2->memory[i - 1] && j < m)
{
j++;
if (list3->memory[j] == list2->memory[i - 1])
{
deleteList(list3, j);
}
}
}
return list3;
}
struct SqList* MergeList_Sq(struct SqList* list1, struct SqList* list2)
{
int m = list1->length;
int n = list2->length;
int* pa = list1->memory;
int* pb = list2->memory;
struct SqList* list3 = initList();
int* pc = list3->memory;
list3->length = m + n;
int* pa_last = list1->memory + list1->length - 1;
int* pb_last = list2->memory + list2->length - 1;
while (pa <= pa_last && pb <= pb_last)
{
if (*pa <= *pb)
*pc++ = *pa++;
else
*pc++ = *pb++;
}
while (pa <= pa_last)
*pc++ = *pa++;
while (pb <= pb_last)
*pc++ = *pb++;
return list3;
}
三、链表
- 定义:用一组任意的存储单元存放线性表中的数据元素,用额外的方式(指针、地址。位置等)存储数据元素间的关系。
- 特点:
- 分类
struct Node
{
int data;
struct Node* left;
struct Node* right;
}
struct Node* createNode(int data)
{
struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
assert(newNode);
newNode->data=data;
newNode->left=NULL;
newNode->right=NULL;
return newNode;
}
struct List
{
struct Node* firstNode;
struct Node* lastNode;
int size;
}
struct List* createList()
{
struct List* list = (struct List*)malloc(sizeof(struct List));
assert(list);
list->firstNode=NULL;
list->lastNode=NULL;
list->size=0;
return list;
}
void push_front(struct List* list, int data)
{
struct Node* newNode=createNode(data);
if(list->size==0)
{
list->lastNode=newNode;
}
else
{
newNode->rigt=list->firstNode;
list->firstNode=newNode;
}
list->firstNode->left=newNode;
list->size++;
}
void push_back(struct List* list, int data)
{
struct Node* newNode=createNode(data);
if(list->size==0)
{
list->firstNode=newNode;
}
else
{
list->lastNode->right=newNode;
newNode->left=list->lastNode;
}
list->lastNode=newNode;
list->size++;
}
void push_Appoin(struct List* list, int data, int posData)
{
struct Node* posNode=list->firstNode;
struct Node* preNode=NULL;
while(posNode != NULL && posNode->data != posData)
{
preNode=posNode;
posNode=posNode->next;
}
if(posNode==NULL)
{
printf("未找到无法插入!\n");
return;
}
else if(posNode == list->firstNode)
{
push_front(list,data);
}
else
{
struct Node* newNode=createNode;
preNode->right = newNode;
newNode->left=preNode;
newNode->right=posNode;
posNode->left=newNode;
list->size++;
}
}
void pop_front(struct List* list)
{
if(list->size==0)
{
printf("链表为空,无法删除!\n");
return;
}
struct Node* nextNode=list->firstNode->right;
free(list->firstNode);
list->firstNode=nextNode;
if(list->size==1)
list->lastNode=NULL;
else
nextNode->left=NULL;
list->size--;
}
void pop_back(struct List* list)
{
if(list->size==0)
{
printf("链表为空,无法删除!\n");
return;
}
struct Node* preNode=list->lastNode->left;
free(list->lastNode);
list->lastNode=preNode;
if(list->size==1)
list->firstNode=NULL;
else
preNode->right=NULL;
list->size--;
}
void print_front(struct Node* list)
{
struct Node* pMove=list->firstNode;
while(pMove != NULL)
{
printf("%d\t",pMove->data);
pMove=pMove->right;
}
printf("\n");
}
void print_back(struct Node* list)
{
struct Node* pMove=list->lastNode;
while(pMove != NULL)
{
printf("%d\t",pMove->data);
pMove=pMove->left;
}
printf("\n");
}
struct Node
{
int data;
struct Node* left;
struct Node* right;
}
struct Node* createList()
{
struct Node* headNode=(struct Node*)malloc(sizeof(struct Node));
assert(headNode);
headNode->left=headNode;
headNode->right=headNode;
return headNode;
}
struct Node* createNode(int data)
{
struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
assert(newNode);
newNode->left=NULL;
newNode->right=NULL;
newNode->data=NULL;
return newNode;
}
void insertByBack(struct Node* heqdNode, int data)
{
struct Node* newNode=createNode(data);
headNode->left->right=newNode;
newNode->right=headNode;
newNode->left=headNode->left;
headNode->left=newNode;
}
void insertAppoin(struct Node* headNode, int data, int posData)
{
struct Node* posNode=headNode->left;
struct Node* preNode=headNode;
while(posNode!=headNode&&posNode->data!=posData)
{
preNode=posNode;
posNode=posNode->right
}
if(posNode==headNode)
{
printf("没有找到指定位置无法插入!\n");
return;
}
else
{
struct Node* newNode=createNode(data);
preNode->right=newNode;
newNode->left=preNode;
newNode->right=posNode;
posNode->left=newNode;
}
}
void printByRight(struct Node* headNode)
{
struct Node* pMove=headNode->right;
whlie(pMove!=headNode)
{
printf("%d\t", pMove->data);
pMove=pMove->right;
}
printf("\n");
}
void printByLeft(struct Node* headNode)
{
struct Node* pMove=headNode->left;
whlie(pMove!=headNode)
{
printf("%d\t", pMove->data);
pMove=pMove->left;
}
printf("\n");
}
四、练习题