2.查找
1)按序号查找
在单链表中,由于每个结点的存储位置都放在其前一结点的next域中,因而即使知道被访问结点的序号i,也不能像顺序表那样直接按序号i访问一维数组中的相应元素,实现随机存取,而只能从链表的头指针出发,顺链域next诸葛结点往下搜索,直至搜索到第i个结点为止。
算法描述:设带头结点的单链表的长度为n,要查找表中第i个结点,则需要从单链表的头指针L出发,从头结点(L->next)开始顺着链表扫描,用指针p指向当前扫描到的结点,初值指向头结点,用j左计数器,累计当前扫描过的结点数(初值为0),当j=i时,指针平所致俄结点就是要找的第i个结点。
Node *Get(LinkList L,int i) /*在带头结点的单链表L中查找第i个结点,若找到(1≤i≤n),则返回该结点的存储位置;*/ /*否则追回NULL*/ { int; Node *p; p=L;j=0;/*从头文件开始扫描*/ while(p->next!=NULL&&j<i) { p=p->next;/*扫描下一结点*/ j++;/*已扫描结点计数器*/ } if(i==j) return p;/*找到了第i个结点*/ else return NULL;/*找不到,i≤0或i>n*/ }/*Get*/ 算法 在单链表L中查找第i个结点 |
2)按值查找
算法描述:按值查找是指在单链表中查找是狗有结点值等于e的结点,若有的话,则返回首次找到的其值为e的结点的存储位置,狗则返回NULL。查找过程从单链表的头指针指向的头结点出发,顺着链逐个将结点的值和给定值e作比较。
Node *Locate(LinkList L,ElemType key)
/*在带头结点的单链表L中查找其结点值等于key的结点,若找到则返回该结点的位置p;否则返回NULL*/
Node *Locate(LinkList L,ElemType key) /*在带头结点的单链表L中查找其结点值等于key的结点,若找到则返回该结点的位置p;否则返回NULL*/ { Node *p; p=L->next;/*从表中第一个结点比较*/ while(p!=NULL) if(p->data!=key) p=p->next; else break;/*找到结点key,推出循环*/ return p; }/*Locate*/ 算法 在单链表L中查找值等于key的结点 |
3.单链表插入操作
算法描述:要在带头结点的单链表L中第i个位置插入一个数据元素e,需要首相在单链表中找到第i-1个结点并有指针pre指示,然后申请一个性的结点并由指针s指示,其数据域的值为e,并修改第i-1个结点的指针使其指向s,然后使s结点的指针域指向原第i个结点。插入结点的过程如图2.11所示。
说明:当单链表中有m个结点时,插入位置有m+1个,即1≤i≤m+1.当i=m+1时,认为是在单链表的尾部插入一个结点。
int InsList(LinkList L,int i,ElemType e) {/*在带头结点的单链表L中第i个位置插入值为e的新结点*/ Node *pre,*s; int k; pre=L;k=0; while(pre!=NULL&&k<i-1) /*在第i元素之前插入,则先找到第i-1个元素的存储位置,是指针pre指向它*/ { pre=pre->next; k=k+1; } if(k!=i-1) /*即while循环是因为pre=NULL或i<1而跳出的,所以一定是插入位置不合理所致*/ { printf("插入位置不合理!"); return ERROR; } s=(Node *)malloc(sizeof(Node));/*为e申请一个新的结点并由s指向它*/ s->data=e;/*将待插入结点的值e赋给s的数据域*/ s->next=pre->next;/*完成插入操作*/ pre->next=s; return OK; } 算法 单链表插入操作 |
4.删除
算法描述:与在带头结点的单链表L中删除第i个结点,则首先要通过计数方式找到第i-1个结点并使p指向第i-1个结点,而后删除第i个结点并释放结点空间。删除过程如图2.12所示。
说明:删除算法中的循环条件(p->next!=NULL&&k<i-1)与前插算法中的循环条件(p!=NULL&&k<i-1)不同,因为前插时的插入位置有m+1个(m为当前单链表中数据元素的个数)。i=m=1是指在第m+1个位置前插入,即在单链表的末尾插入。而删除操作中删除的合法位置只有m个,若使用与前插操作相同的循环条件,则会出现指针指控的情况,是删除操作失败。
int InsList(LinkList L,int i,ElemType *e) {/*在带头结点的单链表L中删除第i个元素并将删除的元素保存到变量*e中*/ Node *pre,*r; int k; p=L;k=0; while(p->next!=NULL&&k<i-1) /*寻找被删除结点i的前驱结点i-1使p指向它*/ { p=p->next; k=k+1; } if(k!=i-1)/*即while循环是因为p->next=NULL或i<1而跳出的*/ { printf("删除结点的位置i不合理!"); return ERROR; } r=p->next; p->next=p->next->next;/*删除结点r*/ free(r);/*释放被删除的结点所占的内存空间*/ return OK; } 算法 单链表删除操作 |