数据结构入门系列——线性表的基本操作

顺序表

结构体中存储元素值和顺序表的实际长度。
定义:

#include <iostream>
using namespace std;
#define maxsize 100
typedef struct 
{
	int data[maxsize];
	int length;
}Sqlist;

由于顺序表采用数组存放元素,而数组具有随机存取特性,所以顺序表具有随机存取特性
注意:线性表的顺序是1 2 ·····n,而data的下标是0 1 2 ······(n-1)。
基本函数:

void InitList(Sqlist &l)
{
	l.length = 0;
}
void DestroyList(Sqlist l)
{}
int GetLength(Sqlist l)
{
	return l.length;
}
/*求线性表中第i个元素运算算法*/
int GetElem(Sqlist l, int i, int &x)
{
	if (i<1 || i>l.length)
		return 0;
	else {
		x = l.data[i - 1];
		return 1;
	}
}
/*********>按值查找返回所在线性表的位置<********/
int Locate(Sqlist l, int x)
{
	int i = 0;
	while (i < l.length || l.data[i] != x)
		i++;
	if (i >= l.length)return 0;
	else
		return (i + 1);
}
/*插入元素运算*/
int IneElem(Sqlist &l, int x, int i)
{
	if (i < 1 || i >= l.length) return 0;
	else {
		for (int j = l.length; j > i; j--)
			l.data[j] = l.data[j - 1];
		l.data[i - 1] = x;		
		l.length++;			
		return 1;
	}
}
/*删除表中第i个元素*/
int DelElem(Sqlist &l, int i)
{
	if (i < 1 || i >= l.length) return 0;
	else {
		for (int j = i; j < l.length; j++)
			l.data[j-1] = l.data[j];
		l.length--;
		return 1;
	}
}
void DispList(Sqlist L)
{
	int i;
	for (i = 0; i < L.length; i++)
		cout << L.data[i] << " ";
	cout << "\n";
}
void CreateList(Sqlist &l, int a[], int n)
{
	int k = 0;
	for (int i = 0; i < n; i++)
	{
		l.data[i] = a[i];
		k++;
	}
	l.length = k;
}

链表

单链表

在这里插入图片描述
定义:

#include <iostream>
#include<iomanip>
using namespace std;
typedef struct node
{
	int data;
	struct node *next;
}lnode,*LinkList;

基本函数

void InitList1(lnode **p)
{
	*p = NULL;
	*p = new lnode;
	(*p)->next = NULL;
}
lnode *InitList()
{
	lnode *l = NULL;
	l = new lnode;
	l->next = NULL;
	return l;
}
/*返回指向线性表第i个结点的指针*/
lnode *find(lnode *l, int i)
{
	int j = 0;
	//*************************绝对不是p=l->next;*****************//
	lnode *p = l; 
	while (p&&j < i)
	{
		j++;
		p = p->next;
	}
	if (i == j)return p;
	else return NULL;
}
void InsertList1(lnode *l, int x, int i)
{
	lnode *p = find(l, i-1);//找要插入节点的前节点
	if (!p)return;
	else {
		lnode *s = new lnode;
		s->data = x;
		s->next = p->next;
		p->next = s;
	}
}
/*插入元素到升序链表*/
void InsertList2(lnode *l, int x)
{
	lnode *pre, *p;
	pre = l;
	p = l->next;
	lnode *s = new lnode;
	s->data = x;
	while (p&&p->data < x)
	{
		pre = p;
		p = p->next;
	}
	if (!p)return;
	else {
		s->next = p;
		pre->next = s;
	}
}
int DeleteList(lnode *l, int x)
{
	lnode *p, *pre;
	p = l->next;
	pre = l;
	while (p&&p->data != x)
	{
		pre = p;
		p = p->next;
	}
	if (!p)return 0;
	else {
		pre->next = p->next;
		delete p;
		p = NULL;
		return 1;
	}
}
void OutputList(lnode *l)
{
	lnode *p;
	p = l->next;
	while (p != NULL)
	{
		cout << p->data <<" ";
		p = p->next;
	}
}
/*从前面插入*/
void CreateList(lnode *l)
{
	lnode *pre = l;
	lnode *p;
	int x;
	cin >> x;
	while (x > 0)
	{
		p = new lnode;
		p->data = x;
		pre->next = p;
		pre = p;
		cin >> x;
	}
	pre->next = NULL;
}
/*从后面插入*/
void CreateList2(lnode *l)
{
	lnode *rear = NULL;
	int x; lnode *p;
	cin >> x;
	while (x > 0)
	{
		p = new lnode;
		p->data = x;
		p->next = rear;
		rear = p;
		cin >> x;
	}
	l->next = rear;
}
void main(void)
{
	lnode *p; p = InitList();
	InsertList1(p, 1, 1);
	InsertList1(p, 2, 2);
	InsertList1(p, 3, 3);
	InsertList1(p, 5, 4);
	InsertList1(p, 6, 5);
	InsertList1(p, 7, 6);
	InsertList1(p, 8, 7);
	cout << "please input the data" << endl;
	int i;
	cin >> i;
	InsertList2(p, i);
	cout << "The list is :" << endl;
	OutputList(p);
	cout << "please input the index you want to delete" << endl;
	int q; cin >> q; DeleteList(p, q);
	cout << "The list is:" << endl;
	OutputList(p);
}

循环单链表

在循环单链表L中,p所指结点为尾结点的条件是:p->next==L
在这里插入图片描述
基本函数:

  1. 以p!=L作为循环条件,当p==L时循环结束,此时p回过来指向头结点,所以p应该初始化指向第一个数据结点而不是头结点,否则循环内的语句不会执行。
  2. 扫描指针p的初始化为p=L,循环的条件应该为
    p->next!=L,当p->next==L时循环结束,此时p指向尾结点。
lnode *InitList()
{
	lnode *l = new lnode;
	l->next = l;
	return l;
}
void DestroyList(lnode *l)
{
	lnode *pre = l;
	lnode *p = l->next;
	while (p != l)
	{
		delete pre;
		pre = p;
		p = p->next;
	}
	delete pre;
}
int GetLength(LinkList L)
{
	int i = 0;
	lnode *p = L->next;
	while (p != L)
	{
		i++;
		p = p->next;
	}
	return i;
}

循环链表有利于表的处理

双向链表

llinkdatarlink
前驱结点数据后驱结点

插入:右左右左
在这里插入图片描述

void  inserdoublink(DnLink &hd,int x,int y)
//在以hd为头指针的双向链表中的数域等于x的结点右边插入含y值的结点
{
	p = hd->Rlink;  //p指向链表的第一个结点
	while ((p != hd) && (p->data != x))
		p = p->Rlink;  //查找结点x
	if (p == hd)
		return;
	else
	{
		q = new DbNode;      //  申请一个新的结点  //
		q->data = y;
		q->Rlink = p->Rlink;
		q->Llink = p;
		(p->Rlink)->Llink = q;
		p->Rlink = q;
	}
}

删除:

//把p赋值给q
(p->Llink)->Rlink=p->Rlink;   //修改前驱结点的右链域
(p->Rlink)->Llink=p->Llink ;   //修改后继结点的左链域 
delete(q);                           

双向链表克服单链表的单向性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值