顺序表
结构体中存储元素值和顺序表的实际长度。
定义:
#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。
基本函数:
- 以p!=L作为循环条件,当p==L时循环结束,此时p回过来指向头结点,所以p应该初始化指向第一个数据结点而不是头结点,否则循环内的语句不会执行。
- 扫描指针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;
}
循环链表有利于表的处理
双向链表
llink | data | rlink |
---|---|---|
前驱结点 | 数据 | 后驱结点 |
插入:右左右左
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);
双向链表克服单链表的单向性。