// 19天勤数据结构课后习题可运行代码--第二章
#include "stdafx.h"
/*
题号:p40-(二)-1-(3)
功能:顺序表元素逆序
思路:交换第一个元素和最后一个元素,第二个和倒数第二个,一直交换到两个元素为同一个元素时,停止交换
*/
int main(int argc, char *argv[])
{
int a[] = {1, 2, 3, 4, 5, 1};
int tmp = 0;
int arrSize = sizeof(a)/sizeof(int);
for (int i = arrSize-1, j = 0; i > j; i--, j++) {
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
for (int i = 0; i < arrSize; i++)
printf("%d", a[i]);
return 0;
}
/*
题号:p40-(二)-1-(4)
功能:顺序表删除i~j的元素
思路:将j到表长度的元素填到删除部分后,更新表长度即可
*/
#define maxSize 100
typedef struct {
int data[maxSize];
int len;
}sqlist;
void delPart(sqlist &L, int i, int j)
{
int delta = j - i + 1;
for (int k = j + 1; k < L.len; k++) // 将j到表长度的元素填到删除部分
L.data[k - delta] = L.data[k];
L.len -= delta; // 更新表长
}
int main(int argc, char *argv[])
{
sqlist L;
L.len = 10;
for (int i = 0; i < 10; i++)
L.data[i] = i;
delPart(L, 2, 5);
for (int k=0; k<L.len; k++)
printf("%d", L.data[k]);
getchar();
}
/*
题号:p40-(二)-1-(5)
功能:小于第一个元素的值在前部分,大于的值在后部分:顺序表实现
思路:遍历数组,将小于第一个元素的值放在一个数组,大于的值在另外一个数组,然后合并两个数组
*/
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {5,1,6,3,7,5,4,85,412,1,3};
int b[11];
int c[11];
int j = 0, k = 0;
// 遍历数组,将小于第一个元素的值放在一个数组,大于的值在另外一个数组
for (int i = 1; i < sizeof(a)/sizeof(int); i++)
{
if (a[0] < a[i]) {
c[j] = a[i];
j++;
} else {
b[k] = a[i];
k++;
}
}
// 合并两个数组
for (int i = 1, k1 = 0; k1 < k; i++, k1++)
{
a[i] = b[k1];
//printf("%d ", b[k1]);
}
for (int i = k+1, j1 = 0; j1 < j; i++, j1++)
{
a[i] = c[j1];
//printf("%d ", c[j1]);
}
for (int i = 0; i < sizeof(a)/sizeof(int); i++)
{
printf("%d ", a[i]);
}
getchar();
return 0;
}
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct Node{
DataType data;
struct Node *next;
}List, Node;
#define Num 5
List* InitList();
void CreateListTail(List *L, int n);
void TraverseList(List *L);
void delSameElem(List *L); // 删除递增非空链表相同元素
void delMin(List *L); // 删除链表最小节点
void reverseLink(List *L); // 逆序单链表
void separateAandB(List *AL, List *&BL); // 将A链表中的奇数元素保留,偶数元素放到B表
// 删除单链表中重复元素:单链表实现
int _tmain(int argc, _TCHAR* argv[])
{
int n, pos, input;
List *L, *BL = NULL;
L = InitList();
/*CreateListHead(L, Num);
printf("线性表的长度是%d\n", Length(L));
TraverseList(L);*/
CreateListTail(L, Num);
TraverseList(L);
delMin(L);
TraverseList(L);
reverseLink(L);
TraverseList(L);
separateAandB(L, BL);
TraverseList(L);
TraverseList(BL);
// delete the same elem
delSameElem(L);
TraverseList(L);
return 0;
}
//链表初始化(即分配头结点的内存空间)
List* InitList()
{
List *L;
L = (List*)malloc(sizeof(List));
if (!L)
{
printf("初始化失败");
exit(1);
}
L->next = NULL;//头结点指针域为空
return L;
}
//创建带头结点的线性表(尾插法)
void CreateListTail(List *L, int n)
{
int i, data;
Node *p,*r = L;
for (i = 0; i < n; i++)
{
p = (Node*)malloc(sizeof(Node));
printf("请输入数据:\n");
scanf_s("%d", &data);
p->data = data;
r->next = p;//确定逻辑关系
r = p;
}
r->next = NULL;
}
//遍历线性表
void TraverseList(List *L)
{
Node *r = L;
printf("链表中的元素依次为:");
while (r->next)
{
r = r->next;
printf("%d ", r->data);
}
printf("\n");
}
/*
题号:p40-(二)-1-(6)
功能:删除递增非空链表中的重复元素
思路:遍历所有结点,前后两个结点如果相等,那么把后驱结点删除
*/
void delSameElem(List *L)
{
Node *p = L->next, *tmp = NULL;
while (p->next) { // 遍历所有结点
if (p->next->data == p->data) { // 前后两个结点如果相等,那么把后继结点删除
// 删除后继结点
tmp = p->next;
p->next = tmp->next;
free(tmp);
} else p = p->next;
}
}
/*
题号:p40-(二)-1-(7)
功能:删除链表中的一个(注意是一个,而不是所有)最小节点
思路:遍历所有结点,记录最小结点指针和前驱节点,遍历结束后,利用最小结点的前驱结点和当前结点指针删除最小结点
*/
void delMin(List *L)
{
Node *pre=L, *p=pre->next,*minp=p,*minpre=pre; // pre指向当前结点的前一个结点,p指向当前结点,minp指向最小结点,minpre指向最小结点的前一个结点
while(p!=NULL) {
if(p->data < minp->data) { // 如果当前结点的值比最小结点的值还小,更新最小结点和最小结点前一个结点
minp = p; // 更新最小结点
minpre = pre; // 更新最小结点前一个结点
}
// 遍历至下一个结点
pre = p;
p = p->next;
}
minpre->next=minp->next;
free(minp);
}
/*
题号:p40-(二)-1-(8) 单链表逆序
功能:逆序单链表
思路:引入头插法概念,使用头插法使元素逆序
*/
void reverseLink(List *L)
{
Node *p = L->next, *nextP = NULL; // 准备p指向L的下一个节点, nextP为p的下一个节点指针
L->next = NULL; // 截断L的后路,让这个表变成空表
while (p != NULL)
{
// 准备p的下一个节点指针
nextP = p->next;
// 开始头插法
p->next = L->next;
L->next = p;
// 让p指向p的下一个节点
p = nextP;
}
}
/*
题号:p40-(二)-1-(9) 奇数结点保留在原单链表,偶数结点放到新单链表
功能:将A链表中的奇数元素保留,偶数元素放到B表
思路:遍历A中的所有元素,如果是偶数,就取下并使用尾插法放到B后,否则不动
*/
void separateAandB(List *AL, List *&BL)
{
Node *pa = AL;
BL = (List *)malloc(sizeof(List));
BL->next = NULL;
Node *pb = BL, *tmp = NULL;
// 开始遍历A链表
while (pa->next) {
if (pa->next->data % 2 == 0) { // 如果pa的下一个结点是偶数,那么摘下下一个结点,插到B后面
// 使临时指针tmp指向pa的下一个结点
tmp = pa->next;
// 开始摘除结点
pa->next = tmp->next;
tmp->next = NULL;
// 把摘除的结点使用尾插法插到B后
pb->next = tmp;
pb = tmp;
} else pa = pa->next;
}
}