数据结构:顺序+链式线性表(C语言)

写线性表的时候,简直离大谱的出现了很多问题,如下。  


顺序线性表 

目标:动态存储的线性表顺序表示和实现,重点实现“插入和删除”操作。

思考:1创建线性表2初始化3插入/删除操作4验证结果。

1.创建线性表

使用动态存储的方式,可以对于线性表动态增添。

数据结构定义:

typedef struct {
	int *elem;   //储存空间基址
	int length;  //当前长度
	int listsize;//当前分配的储存空间容量
}List;

2.初始化新的线性表

List Creatlist(List L) {
	L.elem = (int*)malloc(100 * sizeof(int));//新基质
	if (!L.elem)	exit(-1);//分配失败
	L.length = 0;//空表,长度为0
	L.listsize = 100;//初始存储空间。如果空间不够,可以继续分配。
	return L;
}

从这里开始出现问题:

(1).参数是List L还是List *L?

查了似乎大概应该是*L,但是吧:

 而我去掉*之后:

 

 错误只有这一个了!

 E0153表达式必须具有类类型,但它具有类型 "List *" ;把L.elem改成L->elem的错误。改了就好了  

解答:因为C语言无法使用引用,但是有需要改变传入结构体的值,所以这个函数的入口参数定义为指针型,在调用函数时传入的为结构体的地址。

来自c橘子

 (记住了记住了!)但是如果我又改成*L了是不是就不用->用.就可以?

List* Creatlist(List *L) {
	L->elem = (int*)malloc(100 * sizeof(int));//新基质
	if (!L->elem)	exit(-1);//分配失败
	L->length = 0;//空表,长度为0
	L->listsize = 100;//初始存储空间。如果空间不够,可以继续分配。
	return L;
}

2.查到的几种方法创建顺序表

①creat函数不需要参数,当调用的时候返回值return返回一个指针(List*)。这样初始化的过程就是:没有指向的指针-->指向一个空List的指针。

②采用指向指针的指针作为函数的参数,通过这个参数,把结果带回主调函数。参数为(List**L)返回值(void)

指针的引用作为函数的参数,通过这个参数,把结果带回主调函数。此时参数为(List*&L)。

所以,选择正确的哪一种都可以。 

3.线性表插入元素


List* Insertlist(List* L, int n, int e) {
	//参数:List,插入位置,新元素
	//判读能否插入
	if (n<1 || n>L->length + 1)
		exit(-1);
	if (L->length == L->listsize)
	{
		//需要增加空间分配
		int* newbase;
		newbase = (int*)realloc(L->elem, (L->listsize + 10) * sizeof(int));
		if (newbase)exit(-1);
		L->elem = newbase;//更改了基质
		L->listsize += 10;//每次增加10个储存单元
	}
	int* q = &(L->elem[n - 1]);//要插入的位置
	int* p = &(L->elem[L->length - 1]);
	for (; p >= q; p--)
		*(p + 1) = *p;
	*q = e;
	L->length++;
	printf("\n现在的List为:");//检查一下结果
	for (p = L->elem; *p; p++)
		printf("%d ", *p);
	return L;
}

竟然没有报错。 

后面回过头测试发现了一些问题。这里 for (p = L->elem; *p; p++)        printf("%d ", *p);是不对的。这样后面的地方会出现乱码。我添加了count控制打印的个数。

4.线性表删除元素

List* Dellist(List* L, int n)
{
	if (n<1 || n>L->length)
		exit(-1);
	int*p = &(L->elem[n - 1]);//被删除元素位置
	printf("DELETE:%d", *q);
	int*q = L->elem+L->lenght - 1;//表尾位置
	for (p++; p <= q; ++p)
		*(p - 1) = *p;
	L->length--;
	return L;
}

 5.测试代码

1. C2601    “main”: 本地函数定义是非法的 检查大括号。main的位置有误。

2. C4700    使用了未初始化的局部变量“lista”      

这个问题在修改初始化方法之后得到了解决。

最终的代码

我突然发现了我最大的问题是条件句判断不可能判断成判断可能了少了个‘!’。

现在看起来暂时是没有问题的啦! 

 修改以后,完整的代码:

//线性表顺序结构
#include<stdio.h>
#include<stdlib.h>
typedef struct {
	int *elem;   //储存空间基址
	int length;  //当前长度
	int listsize;//当前分配的储存空间容量
}List;
//函数
// 1初始化
List* Creatlist() {
	List* L= (List*)malloc(sizeof(List));
	L->elem= (int*)malloc(100 * sizeof(int));//新基质
	if (!L->elem)	exit(-1);//分配失败
	L->length = 0;//空表,长度为0
	L->listsize = 100;//初始存储空间。如果空间不够,可以继续分配。
	return L;
}

// 2插入
void Insertlist(List* L, int n, int e) {
	//参数:List,插入位置,新元素
	//判读能否插入
	if (n<1 || n>L->length + 1)
		exit(-1);
	if (L->length == L->listsize)
	{
		//需要增加空间分配
		int* newbase;
		newbase = (int*)realloc(L->elem, (L->listsize + 10) * sizeof(int));
		if (!newbase)exit(-1);
		L->elem = newbase;//更改了基质
		L->listsize += 10;//每次增加10个储存单元
	}
	int* q = &(L->elem[n - 1]);//要插入的位置
	int* p = &(L->elem[L->length - 1]);
	for (; p >= q; p--)
		*(p + 1) = *p;
	*q = e;
	L->length++;
	int count = 0;
	printf("\n现在的List为:");//检查一下结果
	for (p = L->elem; count < L->length; p++)
	{
		printf("%d ", *p); count++;
	}
	return ;
}

void Dellist(List* L, int n)
{
	if (n<1 || n>L->length)
		exit(-1);
	int*p = &(L->elem[n - 1]);//被删除元素位置
	printf("\nDELETE:%d", *p);
	int*q = L->elem+L->length - 1;//表尾位置
	for (p++; p <= q; ++p)
		*(p - 1) = *p;
	L->length--;
	int count = 0;
	printf("\n现在的List为:");//检查一下结果
	for (p = L->elem; count < L->length; p++)
	{
		printf("%d ", *p); count++;
	}
	return;
	return ;
}
// 3测试
int main() 
{
	List * lista = Creatlist();
	printf("运行了吗?");
	Insertlist(lista, 1, 1);
	Insertlist(lista, 2, 2);
	printf("真的运行了吗?");
	Insertlist(lista, 3, 3);
	Insertlist(lista, 2, 4);
	Dellist(lista, 2);
	getchar();
	return 1;
}

我の参考

1关于C语言的realloc函数功能。

参考:https://www.cnblogs.com/ladd/archive/2012/06/30/2571420.html

2关于指针的使用,线性表的一些基本性质概念。

参考https://blog.csdn.net/qq_35924276/article/details/79877322

链式线性表

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node* next;
}Node;//定义节点
//创建链表
Node* Creatnode()
{
	Node* L = (Node*)malloc(sizeof(Node));
	if (!L)
		exit(-1);
	L->next = NULL;
	return L;
 }
//检查线性表
void Checknode(Node* head)
{
	printf("now check my list:");
	for (head=head->next; head != NULL; head = head->next)
		printf("- %d", head->data);
	printf("\n");
}
//插入节点
Node* Insertnode(Node* head, int n, int elem)
{
	int count = 0; Node* p = head; 
	for (; p->next!=NULL ; p = p->next,count++)
	{
		if (count == n)
		{
			Node* L = (Node*)malloc(sizeof(Node));
			L->data = elem;
			L->next = p->next;
			p->next = L;
			break;
		}
	}
	return head;
}
//添加节点
Node* Addnode(Node* head,  int elem)
{
	Node* p = head;
	for (; p->next != NULL; p = p->next)		;
	Node* L = (Node*)malloc(sizeof(Node));
	L->data = elem;L->next = NULL;
	p->next = L;
	return head;
}
//寻找节点
void Getelem(Node* head, int elem)
{
	for (; head->next != NULL; head = head->next)
	{
		if (head->data==elem)
		{
			printf("find %d\n",elem);
			return;
		}
	}
	printf("do not find %d\n", elem);
 }
// 删除节点(这个不好应该P2移动)
Node* Delnode(Node* head,int elem ) {
	Node* p = head; 
	Node* p2 = head;p2= p2->next;
	for (; p2->next != NULL; p2 = p2->next,p=p->next)
	{
		if (p2->data == elem)//删除元素
		{
			printf("delete %d\n", elem);
			p->next = p2->next;
			free(p2);
			return head;
		}
	}
	printf("do not find %d\n", elem);
	return head;
}

int main()
{
	Node* head = Creatnode();
	head = Addnode(head, 1);
	head = Addnode(head, 2);
	head = Insertnode(head, 1, 3);
	Checknode(head);
	head = Delnode(head, 3);
	Checknode(head);
	Getelem(head, 3); Getelem(head, 1);
	getchar();
	return 0;
}

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值