南理工ds期末以及824真题算法汇总
单链表
-
带头结点的递增有序单链表heada和headb,存储的分别为A和B,要求完成差集A-B的算法void difference(heada, headb, n),同时返回A集合中的元素个数
-
因为A和B都是递增有序单链表,一趟遍历,同时遍历链表A和链表B,p指向A,q指向B,当前遍历的两个链表的结点,若p与q所指链表结点大小相同,删掉A中p所指结点,若p所指结所指点小于q所指结点,指针p后移,否则指针q后移
void Difference(LinkList A, LinkList B, int &n){
n = 0;
LNode *p, *q, *pre, *s;
pre = A;
p = A->next;
q = B->next;
while(p != NULL && q != NULL){
if(p->data < q->data){
pre = p
p = p->next
n++;
}else if(p->data > q->data){
q = q->next;
}else{
pre->next = p->next;
s = p;
free(s);
p = p->next;
}
}
}
-
已知头指针分别为la和lb的带头结点的单链表,结点按元素非递减有序排列,写出将la和lb两链表归并成一个结点按元素值非递减有序排列的单链表
-
基本思想: pa指向链表A的第一个结点,pb指向A的第一个结点,链表A指,空作为结果链表同,步遍历链表A和B,比较大小,将较小的的结点头插法插入到链表A中,较小的链表后移指针在同步,遍历结束后,较长的链表未遍历的部分,头插法插入到链表A中
void MergeList(Listlist &La, Listlist &Lb){
LNode *r, *pa = La->next, *pb = Lb->next;
La->next = NULL;
while(pa != NULL && pb != NULL){
if(pa->data <= pb->data){
r = pa->next;
pa->next = La->next;
La->next = pa;
pa = r;
}else{
r = pb->next;
pb->next = La->next;
La->next = pb;
pb = r;
}
}
if(pa != NULL){
pb = pa;
}
while(pb != NULL){
r = pb->next;
pb->next = La->next;
La->next = pb;
pb = r;
}
free(Lb);
}
- 已知一个带头结点单链表中,在链表中,第一个值为x的数据后插入值为y的结点,该结点不存在,在链表最后插入y结点
void insertxy(Lnode &head, int x, int y){
LNode *p;
p = head->next;
bool flag = false;
while(p != NULL){
if(p->data == x){
LNode *s = (LNode*)malloc(sizeof(LNode));
s->next = p->next;
p->next = s;
flag = true;
break;
}
}
if(flag){
LNode *s = (LNode*)malloc(sizeof(LNode));
s->next = NULL;
p->next = s;
}
}
-
已知一无表头结点的单链表以H为头指针,每个结点的data存放一个自然数,统计该链表中偶数的个数
-
基本思想: 遍历链表,统计模除2结果为零的数的个数
int count(LinkList la){
p = la;
int _count = 0;
while(p != NULL){
if(p->data % 2 == 0){
_count++;
}
p = p->next;
}
return _count;
}
-
已知一个带有头结点的单链表,在第一个关键字为X的后面插入Y,如果没有X在链尾插入Y
-
基本思想: 遍历单链表,若找到data域为X的结点,在后面插入Y,若找不到链表尾部插入Y
typedef struct node{
int data;
Node* next;
}node;
void insert(LinkList &L, int x, int y){
LinkList p = L->next;
while(p && p->data != x){
p = p->next;
}
LinkList s = (LinkList*)malloc(sizeof(LinkList));
s->data = y;
s->next = p->next
p->next = s;
}
-
设有线性表L={a1, a2, …, an},顺序存储,试写一个算法将线性表的元素按照原始顺序构造一个有头结点的单链表
-
基本思想: 遍历线性表L,采用尾插法建立单链表(如果逆序,则用头插法)
typedef struct{
ElemType *elem;
int length;
int listSize;
}Sqlist;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkLIst;
LinkList Convert(Sqlist L){
LinkList *r, *s;
La = (LinkList*)malloc(sizeof(LinkList));
r = La;
for(int i = 0; i < L.length; i++){
s = (LinkList*)malloc(sizeof(LinkList));
// 数组名世纪上就是第一个元素的指针
s->data = *(L.elem + i);
r->next = s;
r = s;
}
r->next = NULL;
}
- 无头节点单链表逆置且表头指针指向原链表最后一个结点
void Inverse(&h){
if(h == NULL || h->next == NULL){
return;
}
p = h->next;
pr = NULL;
while(p != NULL){
p->next = pr;
pr = h;
h = p;
p = h->next;
}
h->next = pr;
}
-
判断一个偶数个元素的单链表是否是对称串,这个函数时间复杂度O(n)
-
基本思想: 运用快慢指针,同时遍历链表,慢指针遍历过的元素压入栈中,快指针指向元素的next为空停止遍历;从慢指针指向的元素开始遍历,同时比较出栈的元素,若不同则不是对称串,直到表尾,遍历结束
-
如果是奇数,慢指针需要后移一位
bool Is_symmetrical(char* head){
LNode *fast, *slow;
fast = slow = head;
bool flag = true;
Stack <char>st;// 声明一个栈
while(fast->next != NULL){
st.push(fast->data);
fast = fast->next->next;
slow = slow->next;
}
while(slow != NULL){
if(slow->data != st.pop()){
flag = false;
break;
}
}
return flag;
}
-
带头结点的单链表删除最小值结点(删除最大值同理)
-
基本思路: 遍历单链表,指针p指向遍历的当前元素,指针pre指向p的前驱,指针min指向每次比较得出的最小值,指针r指向min的前驱,遍历结束后,指针r的next指向指针min所指元素的next,释放指针min所指元素
typedef struct LNode{
ElemType data;
struct LNode *next;
}Lnode, *LinkList
void DelMinNode(LinkList &head){
LNode *p, *pre, *min, *r;
pre = head;
p = head->next;
min = p;
while(p != NULL){