01-线性结构

线性结构

一、认识线性表

  • 定义:
    线性表是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();
//按值查找:找出等于x的值的结点
int locateItem(struct SqList* MyList, int x);
//求表的长度
int ListLength(struct SqList* MyList);
//提取函数:在表中提取第i个元素的值
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;
}
//按值查找:找出等于x的值的结点
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;
}
//提取函数:在表中提取第i个元素的值
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;
}

三、链表

  • 定义:用一组任意的存储单元存放线性表中的数据元素,用额外的方式(指针、地址。位置等)存储数据元素间的关系。
  • 特点:
    • 链式存储结构
    • 存储单元可以不连续
    • 顺序存储
  • 分类
    • 循环链表
    • 双向链表
//双向链表
//1.抽象单一个体
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->firstNode=newNode;
        list->lastNode=newNode;
        //list->size++;
    }
    else
    {
        newNode->rigt=list->firstNode;
        //list->firstNode->left=newNode;
        list->firstNode=newNode;
        //list->size++;
    }
    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;
        //list->lastNode=newNode;
        //list->size++;
    }
    else
    {
        list->lastNode->right=newNode;
        newNode->left=list->lastNode;
        //list->lastNode=newNode;
        //list->size++;
    }
    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最后一个节点
    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");
}



四、练习题

  • n皇后问题(爬山法)
Created with Raphaël 2.3.0 开始 随机生成或指定生成一个初始棋盘x 计算棋盘的分数f(x) 用邻居算子生成邻居链表xList 判断xList中存在x'的评价优于x的评价? 选择评价最优的x'或随机选择较优的x' x <- x' 更新邻居列表xList 返回x 结束 yes no
  • 遗传算法
Created with Raphaël 2.3.0 开始 初始化 满足停止条件? 返回P 结束 交叉算子操作,p' <- p 变异算子操作,p" <- p' 计算p"中个体的适应度值 选择算子操作,p <- p + p" yes no
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值