数据结构C语言版算法大全
- 格式:doc
- 大小:330.91 KB
- 文档页数:25
1) 插入操作
在顺序表L的第i (1<=L.length+1)个位置插入新元素e。如果i的输入不合法,则返回false,表示插入失败;否则,将顺序表的第i个元素以及其后的元素右移一个位置,腾出一个空位置插入新元素e,顺序表长度增加1,插入成功,返回true。
1. bool ListInsert(SqList &L, int i, ElemType e){
2. //本算法实现将元素e插入到顺序表L中第i个位置
3. if ( i<1 || i>L.length+1 )
4. return false; // 判断i的范围是否有效
5. if(L.length>=MaxSize)
6. return false; // 当前存储空间已满,不能插入
7. for (int j =L.length; j >=i; j--) // 将第i个位置及之后的元素后移
8. L.data[j]=L.data[j-l];
9. L.data[i-1]=e; //在位置i处放入e
10. L.length++; //线性表长度加1
11. return true;
12. }
2) 删除操作
删除顺序表L中第i (1<=i<=L.length)个位置的元素,成功则返回true,否则返回false,并将被删除的元素用引用变量e返回。
复制纯文本新窗口
1. bool ListDelete(SqList &L,int i, int &e){
2. //本算法实现删除顺序表L中第i个位置的元素
3. if(i<1 || i>L.length)
4. return false; // 判断i的范围是否有效
5. e=L.data[i-1] ; // 将被删除的元素赋值给e
6. for (int j=i; j
7. L.data[j-1]=L.data[j]; 8. L.length--; //线性表长度减1
9. return true;
10. }
3) 按值查找(顺序查找)
在顺序表L中查找第一个元素值等于e的元素,并返回其下标。
1. int LocateElem(SqList L, ElemType e){
2. //本算法实现查找顺序表中值为e的元素,如果查找成功,返回元素位序,否则返回0
3. int i;
4. for(i=0;i
5. if(L.data[i]==e)
6. return i+1; // 下标为i的元素值等于e,返回其位号i+1
7. return 0; //退出循环,说明查找失败
8. }
单链表的定义
1. typedef struct LNode{ //定义单链表结点类型
2. ElemType data; //数据域
3. struct LNode *next; //指针域
4. }LNode, *LinkList;
采用头插法建立单链表
该方法从一个空表开始,生成新结点,并将读取到的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头,即头结点之后,如图2-4所示。
图2-4 头插法建立单链表
头插法建立单链表的算法如下:
1. LinkList CreatList1(LinkList &L){
2. //从表尾到表头逆向建立单链表L,每次均在头结点之后插入元素
3. LNode *s;int x;
4. L=(LinkList)malloc(sizeof(LNode)); //创建头结点
5. L->next=NULL; //初始为空链表
6. scanf("%d", &x); //输入结点的值
7.
8. while(x!=9999) { //输入 9999 表示结束
9. s=(LNode*)malloc(sizeof(LNode) ); //创建新结点
10. s->data=x;
11. s->next=L->next; //重点(如果使用头插法的话)
12. L->next=s; //将新结点插入表中,L为头指针
13. scanf ("%d", &x);
14. } //while 结束
15.
16. return L;
17. }
采用尾插法建立单链表 头插法建立单链表的算法虽然简单,但生成的链表中结点的次序和输入数据的顺序不一致。若希望两者次序一致,可采用尾插法。该方法是将新结点插入到当前链表的表尾上,为此必须增加一个尾指针r,使其始终指向当前链表的尾结点,如图2-5所示。
图2-5 尾插法建立单链表
尾插法建立单链表的算法如下:
1. LinkList CreatList2(LinkList &L){
2. //从表头到表尾正向建立单链表L,每次均在表尾插入元素
3. int x; // 设元素类型为整型
4.
L=(LinkList)malloc(sizeof(LNode));
5.
LNode *s, *r=L; //r 为表尾指针
6. scanf
("%d", &x); //输入结点的值
7.
8. while
(x!=9999) { //输入 9999 表示结束
9.
s=(LNode *)malloc(sizeof(LNode));
10. s->data=x; //重点
11.
r->next=s;
12.
r=s; //r指向新的表尾结点
13.
scanf ("%d", &x);
14. }
15.
16.
r->next = NULL;
//尾结点指针置空
17. return L;
18. }
按序号查找结点值
在单链表中从第一个结点出发,顺指针next域逐个往下搜索,直到找到第i个结点为止,否则返回最后一个结点指针域NULL。
按序号查找结点值的算法如下:
1. LNode GetElem(LinkList L,int i){
2. //本算法取出单链表L(带头结点)中第i个位置的结点指针
3. int j=1; //计数,初始为1
4. LNode *p = L->next; //头结点指针赋给p //注意
5.
6. if(i==0)
7. return L; //若i等于0,则返回头结点
8. if(i<1)
9. return NULL; //若 i 无效,则返回 NULL
10.
11. while( p && j
12. p=p->next;
13. j++;
14. }
15.
16.
return p;
//返回第i个结点的指针,如果i大于表长,p=NULL,直接返回p即可
17. }
按值查找表结点
从单链表第一个结点开始,由前往后依次比较表中各结点数据域的值,若某结点数据域的值等于给定值e,则返回该结点的指针。若整个单链表中没有这样的结点,则返回NULL。按值查找结点的算法如下:
1.
LNode
LocateElem
(LinkList L, ElemType e)
{
//本算法查找单链表 L (带头结点)中数据域值等于e的结点指针,否则返回NULL
2. LNode *p=L->next;
3. while( p!=NULL && p->data!=e) //从第1个结点开始查找data域为e的结点
4. p=p->next;
5.
6. return p; //找到后返回该结点指针,否则返回NULL
7. }
插入结点操作
插入操作是将值为x的新结点插入到单链表的第i个位置上。先检查插入位置的合法性,然后找到待插入位置的前驱结点,即第i-1个结点,再在其后插入新结点。
算法首先调用上面的按序号查找算法GetElem(L, i-1),查找第i-1个结点。假设返回的第i-1个结点为*p,然后令新结,点*s的指针域指向*p的后继结点,再令结点*p的指针域指向新插入的结点*s。其操作过程如图2-6所示。
图2-6 单链表的插入操作
实现插入结点的代码片段如下: 1.
p=GetElem(L, i-1) ; // 语句①,查找插入位置的前驱结点
2.
s->next=p->next; // 语句②,图 2-6 中辑作步骤 1
3. p->next=s; // 语句③,图2-6中操作步骤2
删除结点操作
删除操作是将单链表的第i个结点删除。先检查删除位置的合法性,然后查找表中第i-1个结点,即被删结点的前驱结点,再将其删除。其操作过程如图2-7所示。
图2-7 单链表结点的删除
假设结点*p为找到的被删结点的前驱结点,为了实现这一操作后的逻辑关系的变化,仅需修改*p的指针域,即将*p的指针域next指向*q的下一结点。
实现删除结点的代码片段如下:
1. p=GetElem(L,i-1); //查找删除位置的前驱结点
2. q=p->next; //令q指向被删除结点
3. p->next=q->next //将*q结点从链中“断开”
4. free (q) ; //释放结点的存储空间
和插入算法一样,该算法的主要时间也是耗费在查找操作上,时间复杂度为O(n)。
扩展:删除结点*p