线性表常见算法实现

线性表常见算法实现

  • 线性表定义(设表内元素都是整型数据)
//定义线性表
struct seqlist
{
	int *a;
	int size;
};

//初始化线性表
void init_seqlist(seqlist* l,int n)
{
	l->a = (int*)malloc(sizeof(int)*n);
	l->size = n;
}
  • 设计一个算法,将顺序表中所有的元素逆置。
//线性表内的元素逆序
void reverse_seqlist(seqlist* l)	
{
	for (int i = 0, j = l->size-1; i <= j; ++i, --j)
	{
		int tmp = l->a[i];
		l->a[i] = l->a[j];
		l->a[j] = tmp;
	}
}
  • 设计一个算法,从一给定的顺序表L中删除下标i~j(i<=j,包括i,j)的所有元素,假定i,j都是合法的。
//从一给定的顺序表L中删除下标i~j(i<=j,包括i,j)的所有元素
void delete_i_to_j(seqlist* l, int i, int j)
{
	for (int p = j + 1,e=i; p < l->size; ++p,++e)
	{
		l->a[e] = l->a[p];
	}
	l->size -= j - i + 1;
}
  • 有一个顺序表L,其元素为整型数据,设计一个算法,将L中所有小于表头元素的整数放在前半部分,大于表头元素的整数放在后半部分
//设计一个算法,将顺序表L中所有小于表头元素的整数放在前半部分,大于表头无素的整数放在后半部分
void compare_with_head(seqlist* l)
{
	int loc = 0;
	for (int i = 1; i < l->size; ++i)
	{
		
		if (l->a[i] < l->a[loc])
		{
			int value = l->a[i];
			for (int j = i ; j>loc; --j)
			{
				l->a[j ] = l->a[j-1];
			}
			l->a[loc++] = value;
		}
	}
}
  • 有一个递增非空单链表,设计一个算法删除值域重复的结点
//有一个递增非空单链表,设计一个算法删除值域重复的结点。
//例如,{1,1,2,3,3,3,4,4,7, 7,7,9, 9, 9},经过删除后变成{1, 2, 3,4, 7, 9}。

//定义节点
struct node
{
	int data;
	struct node* next;
};

//定义单链表
struct linked_list
{
	struct node* head;
};

//单链表添加节点
void linked_list_push(linked_list*l,int x)
{
	struct node*p = (struct node*)malloc(sizeof(struct node));
	p->data = x;
	p->next = NULL;

	if (l->head == NULL)
	{
		l->head = p;
	}
	else
	{
		struct node*q = l->head;
		while (q->next != NULL)
		{
			q = q->next;
		}
		q->next = p;
	}
}

//打印单链表
void print_linked_list(linked_list l)
{
	struct node*q = l.head;
	while (q != NULL)
	{
		printf("%d ", q->data);
		q = q->next;
	}
	printf("\n");
}

//删除单链表中的重复元素
void delete_repeating_elements(linked_list*l)
{
	struct node*p = l->head->next;
	struct node*q = l->head;
	while (p != NULL)
	{
		if (p->data == q->data)
		{
			struct node*r = p;
			q->next = p->next;
			p = p->next;
			free(r);
		}
		else
		{
			p = p->next;
			q = q->next;
		}
	}
}
  • 设计一个算法删除单链表L (有头结点)中的最小值结点
//删除单链表L(有头结点)中的最小值结点。
void delete_linked_list_min(linked_list* l)
{
	//找出最小值
	int min_value = 1000000;
	struct node*p = l->head;
	while (p->next != NULL)
	{
		if (p->data < min_value)
		{
			min_value = p->data;
		}
		p = p->next;
	}

	//遍历去除最小值,初始时p指向第一个元素,q指向第二个元素
	//利用q的值来判断是否需要删去,因此p始终保持指向q前面一个元素
	//所以漏掉了对第一个元素的判断,后面需要补上
	p = l->head;
	struct node*q = p->next;
	while (p->next != NULL)
	{
		if (q->data == min_value)
		{
			struct node*r = q;
			p->next = q->next;
			q = p->next;
			free(r);
		}
		else
		{
			p = p->next;
			q = p->next;
		}		
	}

	//上面的检查漏掉了第一个元素,因此补上
	if (l->head->data == min_value)
	{
		struct node*r = l->head;
		l->head = l->head->next;
		free(r);
	}
}
  • 单链表L,设计一个算法将其逆置,要求不能建立新结点,只能通过表中已有结点的重新组合来完成。
//单链表L,设计一个算法将其逆置
//要求不能建立新结点,只能通过表中已有结点的重新组合来完成
void reverse_linked_list(linked_list* l)
{
	struct node*p;
	struct node*q;
	struct node*r;
	p = l->head;
	q = p->next;
	r = q->next;

	while (r->next != NULL)
	{
		q->next = p;
		p = q;
		q = r;
		r = r->next;
	}
	q->next = p;
	r->next = q;
	l->head->next = NULL;
	l->head = r;
}
  • 设计个算法, 将一个头结点为A的单链表(其数据域为整数),分解成两个单链表A和B,便得A链表只含有原来链表中data域为奇数的结点,而B链表只含有原链表中data域为偶数的结点,且保持原来的相对顺序。

你可能感兴趣的:(CS专业课笔记)